当丹麦语设置为 VM 参数时,org.joda.time.DateTime 的 toString() 方法失败
toString() method of org.joda.time.DateTime failed when Danish is set as VM argument
import java.text.SimpleDateFormat;
import java.util.Locale;
import org.joda.time.DateTime;
import org.joda.time.Interval;
public class JordaTimeTest {
public static void main(String[] args) {
SimpleDateFormat dateFormat1 = new SimpleDateFormat("EEE dd/MM HH:mm", Locale.getDefault());
SimpleDateFormat dateFormat = dateFormat1;
Interval interval = new Interval(1499628963860L, 1511809983860L);
DateTime start = new DateTime(interval.getStart());
DateTime end = new DateTime(interval.getEnd());
System.out.println(start.toString(dateFormat.toLocalizedPattern()));
}
}
我按照How to set eclipse console locale/language
中指定的方式进行了操作
我使用 -Duser.language=da -Duser.country=DK
作为 VM 参数。我遇到异常:
java.lang.IllegalArgumentException: Illegal pattern component: tt
有什么办法解决这个问题吗?
将区域设置设置为 da_DK 时,方法 toLocalizedPattern
returns EEE tt/MM HH:mm
和 tt
is not a recognized pattern 在乔达时代。
如果您希望以特定语言输出,则无需更改 JVM 默认语言环境(因为这会影响同一 JVM 中的所有其他应用程序 运行)。相反,您可以创建一个 org.joda.time.format.DateTimeFormatter
并仅在格式化程序中设置语言环境:
DateTimeFormatter fmt = DateTimeFormat
// set pattern
.forPattern("EEE dd/MM HH:mm")
// set locale
.withLocale(new Locale("da", "DK"));
System.out.println(fmt.print(start));
System.out.println(fmt.print(end));
这将输出:
sø 09/07 16:36
ma 27/11 17:13
请注意,输出取决于 JVM 默认时区:1499628963860
对应于 UTC 2017-07-09T19:36:03.860Z
,在我的 JVM 默认时区 (America/Sao_Paulo
) 中是 16:36 .在您的机器中,这些值会有所不同。
如果您想指定一个时区,您可以像这样创建日期:
// create date in UTC
DateTime start = new DateTime(interval.getStart(), DateTimeZone.UTC);
现在 DateTime
是 UTC,所以输出将是 sø 09/07 19:36
。
您还可以使用 DateTimeZone.forID("zonename")
设置特定时区,其中 zonename
是有效的 IANA timezone name(始终采用 Region/City
格式,例如 America/Sao_Paulo
或 Europe/Berlin
)。
避免使用 3 个字母的缩写(如 CST
或 PST
),因为它们是 ambiguous and not standard.
您可以通过调用 DateTimeZone.getAvailableIDs()
.
获取可用时区列表(并选择最适合您的系统的时区)
如 中所述,无需使用 SimpleDateFormat
(因为它设计用于 java.util.Date
和 java.util.Calendar
)。
Java 新 Date/Time API
Joda-Time 处于维护模式,正在被新的 APIs 取代,所以我不建议用它开始一个新项目。即使在 joda's website 它说:"Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".
如果您不能(或不想)从 Joda-Time 迁移到新的 API,您可以忽略此部分。
如果您正在使用 Java 8,请考虑使用 new java.time API. It's easier, less bugged and less error-prone than the old APIs.
如果您使用 Java 6 或 7,您可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it ).
下面的代码适用于两者。
唯一的区别是包名称(在 Java 8 中是 java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp
),但是 类和方法名称相同。
您不需要创建间隔并从中获取开始和结束。您可以直接创建日期:
// use system default timezone
ZoneId zone = ZoneId.systemDefault();
ZonedDateTime start = Instant.ofEpochMilli(1499628963860L).atZone(zone);
ZonedDateTime end = Instant.ofEpochMilli(1511809983860L).atZone(zone);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE dd/MM HH:mm", new Locale("da", "DK"));
System.out.println(start.format(fmt));
System.out.println(end.format(fmt));
输出为:
sø 09/07 16:36
ma 27/11 17:13
如果你想转换到另一个时区(而不是 JVM 默认值),你可以使用 ZoneId.of("zonename")
,或者 ZoneOffset.UTC
使用 UTC。
SimpleDateFormat dateFormat1 = new SimpleDateFormat("EEE dd/MM HH:mm", Locale.getDefault());
SimpleDateFormat dateFormat = dateFormat1;
DateFormatSymbols dfs = dateFormat.getDateFormatSymbols();
dfs.setLocalPatternChars("GyMdkHmsSEDFwWahKzZ");
dateFormat.setDateFormatSymbols(dfs);
Interval interval = new Interval(1499628963860L, 1511809983860L);
DateTime start = new DateTime(interval.getStart());
DateTime end = new DateTime(interval.getEnd());
System.out.println(start.toString(dateFormat.toLocalizedPattern()));
这是解决问题的另一种方法
它是解释日期和时间的字符集
ex :- y = year
d = day
M = month
m = minutes etc
在 DK 中,t 用于 Y 而 u 用于 d
但是 Joda 时间不支持 t 和 u
import java.text.SimpleDateFormat;
import java.util.Locale;
import org.joda.time.DateTime;
import org.joda.time.Interval;
public class JordaTimeTest {
public static void main(String[] args) {
SimpleDateFormat dateFormat1 = new SimpleDateFormat("EEE dd/MM HH:mm", Locale.getDefault());
SimpleDateFormat dateFormat = dateFormat1;
Interval interval = new Interval(1499628963860L, 1511809983860L);
DateTime start = new DateTime(interval.getStart());
DateTime end = new DateTime(interval.getEnd());
System.out.println(start.toString(dateFormat.toLocalizedPattern()));
}
}
我按照How to set eclipse console locale/language
中指定的方式进行了操作我使用 -Duser.language=da -Duser.country=DK
作为 VM 参数。我遇到异常:
java.lang.IllegalArgumentException: Illegal pattern component: tt
有什么办法解决这个问题吗?
将区域设置设置为 da_DK 时,方法 toLocalizedPattern
returns EEE tt/MM HH:mm
和 tt
is not a recognized pattern 在乔达时代。
如果您希望以特定语言输出,则无需更改 JVM 默认语言环境(因为这会影响同一 JVM 中的所有其他应用程序 运行)。相反,您可以创建一个 org.joda.time.format.DateTimeFormatter
并仅在格式化程序中设置语言环境:
DateTimeFormatter fmt = DateTimeFormat
// set pattern
.forPattern("EEE dd/MM HH:mm")
// set locale
.withLocale(new Locale("da", "DK"));
System.out.println(fmt.print(start));
System.out.println(fmt.print(end));
这将输出:
sø 09/07 16:36
ma 27/11 17:13
请注意,输出取决于 JVM 默认时区:1499628963860
对应于 UTC 2017-07-09T19:36:03.860Z
,在我的 JVM 默认时区 (America/Sao_Paulo
) 中是 16:36 .在您的机器中,这些值会有所不同。
如果您想指定一个时区,您可以像这样创建日期:
// create date in UTC
DateTime start = new DateTime(interval.getStart(), DateTimeZone.UTC);
现在 DateTime
是 UTC,所以输出将是 sø 09/07 19:36
。
您还可以使用 DateTimeZone.forID("zonename")
设置特定时区,其中 zonename
是有效的 IANA timezone name(始终采用 Region/City
格式,例如 America/Sao_Paulo
或 Europe/Berlin
)。
避免使用 3 个字母的缩写(如 CST
或 PST
),因为它们是 ambiguous and not standard.
您可以通过调用 DateTimeZone.getAvailableIDs()
.
如 SimpleDateFormat
(因为它设计用于 java.util.Date
和 java.util.Calendar
)。
Java 新 Date/Time API
Joda-Time 处于维护模式,正在被新的 APIs 取代,所以我不建议用它开始一个新项目。即使在 joda's website 它说:"Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".
如果您不能(或不想)从 Joda-Time 迁移到新的 API,您可以忽略此部分。
如果您正在使用 Java 8,请考虑使用 new java.time API. It's easier, less bugged and less error-prone than the old APIs.
如果您使用 Java 6 或 7,您可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it
下面的代码适用于两者。
唯一的区别是包名称(在 Java 8 中是 java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp
),但是 类和方法名称相同。
您不需要创建间隔并从中获取开始和结束。您可以直接创建日期:
// use system default timezone
ZoneId zone = ZoneId.systemDefault();
ZonedDateTime start = Instant.ofEpochMilli(1499628963860L).atZone(zone);
ZonedDateTime end = Instant.ofEpochMilli(1511809983860L).atZone(zone);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE dd/MM HH:mm", new Locale("da", "DK"));
System.out.println(start.format(fmt));
System.out.println(end.format(fmt));
输出为:
sø 09/07 16:36
ma 27/11 17:13
如果你想转换到另一个时区(而不是 JVM 默认值),你可以使用 ZoneId.of("zonename")
,或者 ZoneOffset.UTC
使用 UTC。
SimpleDateFormat dateFormat1 = new SimpleDateFormat("EEE dd/MM HH:mm", Locale.getDefault());
SimpleDateFormat dateFormat = dateFormat1;
DateFormatSymbols dfs = dateFormat.getDateFormatSymbols();
dfs.setLocalPatternChars("GyMdkHmsSEDFwWahKzZ");
dateFormat.setDateFormatSymbols(dfs);
Interval interval = new Interval(1499628963860L, 1511809983860L);
DateTime start = new DateTime(interval.getStart());
DateTime end = new DateTime(interval.getEnd());
System.out.println(start.toString(dateFormat.toLocalizedPattern()));
这是解决问题的另一种方法
它是解释日期和时间的字符集
ex :- y = year
d = day
M = month
m = minutes etc
在 DK 中,t 用于 Y 而 u 用于 d 但是 Joda 时间不支持 t 和 u