在具有 Windows zulu8 的同一台机器上使用 SimpleDateFormat 使用相同语言环境的不同结果
different results with same locale using SimpleDateFormat on same machine with Windows zulu8
我必须处理 SimpleDateFormat 但我对星期几值有疑问。
为了缩小问题的范围,我在下面编写了简单的 Java 代码,发现 returns 两个不同的结果具有明显相同的设置(只是通过在命令行上强制本地)。
问题仅出现在Windows(美国配置)机器上:如果我运行在Linux(CentOS)机器上进行相同的测试,一切正常。
Windows 上的 JVM 是 zulu8 1.8.0_282 openjdk(但似乎我与 oracle 8 jdk 的行为相同)而它是 Red Hat 1.8.0_272 在 Linux.
上打开 jdk
这是源代码:
import java.util.Locale;
import java.util.Calendar;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
public class TestDate {
public static void main(String args[]) throws ParseException {
Locale currentLocale = Locale.getDefault();
System.out.println(System.getProperty("java.vendor"));
System.out.println(System.getProperty("java.version"));
System.out.println("==============");
System.out.printf("%20s = %s%n", "getDisplayLanguage", currentLocale.getDisplayLanguage());
System.out.printf("%20s = %s%n", "getDisplayCountry", currentLocale.getDisplayCountry());
System.out.printf("%20s = %s%n", "getDisplayVariant", currentLocale.getDisplayVariant());
System.out.printf("%20s = %s%n", "getLanguage", currentLocale.getLanguage());
System.out.printf("%20s = %s%n", "getCountry", currentLocale.getCountry());
System.out.printf("%20s = %s%n", "user.country", System.getProperty("user.country"));
System.out.printf("%20s = %s%n", "user.language", System.getProperty("user.language"));
System.out.printf("%20s = %s%n", "user.variant", System.getProperty("user.variant"));
System.out.println("==============");
Calendar c = Calendar.getInstance();
System.out.println("1st day of week / minimal days in 1st week : " + c.getFirstDayOfWeek() + " / " + c.getMinimalDaysInFirstWeek());
System.out.println("==============");
LocalDate date1 = LocalDate.of(2020, 12, 31);
LocalDate date2 = LocalDate.of(2021, 1, 1);
DateFormat df_date = new java.text.SimpleDateFormat("dd/MM/yyyy");
DateFormat df_week = new java.text.SimpleDateFormat("YYYY-ww");
System.out.printf("%20s | %10s | %10s%n", "", df_date.format(java.sql.Date.valueOf(date1)), df_date.format(java.sql.Date.valueOf(date2)));
System.out.printf("%20s | %10s | %10s%n", "SimpleDateFormat", df_week.format(java.sql.Date.valueOf(date1)), df_week.format(java.sql.Date.valueOf(date2)));
System.out.printf("%20s | %7d-%02d | %7d-%02d%n", "WeekFields",
date1.get(WeekFields.ISO.weekBasedYear()), date1.get(WeekFields.ISO.weekOfWeekBasedYear()),
date2.get(WeekFields.ISO.weekBasedYear()), date2.get(WeekFields.ISO.weekOfWeekBasedYear()));
}
}
这是结果(第二个是预期的):
>java TestDate
Azul Systems, Inc.
1.8.0_282
==============
getDisplayLanguage = English
getDisplayCountry = United States
getDisplayVariant =
getLanguage = en
getCountry = US
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 2 / 4
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2020-53 | 2020-53
WeekFields | 2020-53 | 2020-53
>java -Duser.language=en -Duser.country=US -Duser.variant= TestDate
Azul Systems, Inc.
1.8.0_282
==============
getDisplayLanguage = English
getDisplayCountry = United States
getDisplayVariant =
getLanguage = en
getCountry = US
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 1 / 1
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2021-01 | 2021-01
WeekFields | 2020-53 | 2020-53
两者似乎使用相同的语言环境设置,但 SimpleDateFormat returns 不同 week/year 周。
我是否缺少某些区域设置?
感谢您的帮助。
使用 Oracle JDK 编辑:
>java TestDate
Oracle Corporation
1.8.0_202
==============
getDisplayLanguage = English
getDisplayCountry = United States
getDisplayVariant =
getLanguage = en
getCountry = US
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 2 / 4
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2020-53 | 2020-53
WeekFields | 2020-53 | 2020-53
>java -Duser.language=en -Duser.country=US -Duser.variant= TestDate
Oracle Corporation
1.8.0_202
==============
getDisplayLanguage = English
getDisplayCountry = United States
getDisplayVariant =
getLanguage = en
getCountry = US
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 1 / 1
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2021-01 | 2021-01
WeekFields | 2020-53 | 2020-53
编辑日历默认区域设置:
正如 Scratte 所指出的,Calendar 和 SimpleDateFormat 使用默认的 Locale。我查看了 SimpleDateFormat source code,它使用 Locale.getDefault(Locale.Category.FORMAT)
作为默认 Local,这与我在代码中使用的 Locale.getDefault()
不同。
我终于明白了为什么我在两个代码之间有 2 个不同的行为:我没有显示正确的 Locale(我不知道 3 个不同的 Locale ;谢谢 Ole V.V。澄清这一点) .
TL;DR
SimpleDateFormat
使用 Locale.getDefault(Locale.Category.FORMAT)
而我的 Java 代码显示 Locale.getDefault()
的值。
后者总是 en_US
但前者是 fr_FR
或 en_US
取决于我使用的命令行。这就是为什么我每周/每年有两个不同的输出。
最后,JVM参数-Duser.language= / -Duser.country= / -Duser.variant=
是解决方案(它们强制所有三个不同的Locale)!
这段新代码显示了三种不同语言环境的区别:
import java.sql.Date;
import java.util.Locale;
import java.util.Calendar;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
public class TestDate {
public static void main(String args[]) throws ParseException {
Locale cL = Locale.getDefault();
Locale cLD = Locale.getDefault(Locale.Category.DISPLAY);
Locale cLF = Locale.getDefault(Locale.Category.FORMAT);
System.out.println(System.getProperty("java.vendor"));
System.out.println(System.getProperty("java.version"));
System.out.println("==============");
System.out.printf("%20s | %15s | %15s | %15s%n", "Locale.getDefault(.)", "", "DISPLAY", "FORMAT");
System.out.printf("%20s | %15s | %15s | %15s%n", "getDisplayLanguage", cL.getDisplayLanguage(), cLD.getDisplayLanguage(), cLF.getDisplayLanguage());
System.out.printf("%20s | %15s | %15s | %15s%n", "getDisplayCountry", cL.getDisplayCountry(), cLD.getDisplayCountry(), cLF.getDisplayCountry());
System.out.printf("%20s | %15s | %15s | %15s%n", "getDisplayVariant", cL.getDisplayVariant(), cLD.getDisplayVariant(), cLF.getDisplayVariant());
System.out.printf("%20s | %15s | %15s | %15s%n", "getLanguage", cL.getLanguage(), cLD.getLanguage(), cLF.getLanguage());
System.out.printf("%20s | %15s | %15s | %15s%n", "getCountry", cL.getCountry(), cLD.getCountry(), cLF.getCountry());
System.out.printf("%20s | %15s | %15s | %15s%n", "getVariant", cL.getVariant(), cLD.getVariant(), cLF.getVariant());
System.out.printf("%20s = %s%n", "user.country", System.getProperty("user.country"));
System.out.printf("%20s = %s%n", "user.language", System.getProperty("user.language"));
System.out.printf("%20s = %s%n", "user.variant", System.getProperty("user.variant"));
System.out.println("==============");
Calendar c = Calendar.getInstance();
System.out.println("1st day of week / minimal days in 1st week : " + c.getFirstDayOfWeek() + " / " + c.getMinimalDaysInFirstWeek());
System.out.println("==============");
LocalDate date1 = LocalDate.of(2020, 12, 31);
LocalDate date2 = LocalDate.of(2021, 1, 1);
DateFormat df_date = new java.text.SimpleDateFormat("dd/MM/yyyy");
DateFormat df_week = new java.text.SimpleDateFormat("YYYY-ww");
System.out.printf("%20s | %10s | %10s%n", "", df_date.format(java.sql.Date.valueOf(date1)), df_date.format(java.sql.Date.valueOf(date2)));
System.out.printf("%20s | %10s | %10s%n", "SimpleDateFormat", df_week.format(java.sql.Date.valueOf(date1)), df_week.format(java.sql.Date.valueOf(date2)));
System.out.printf("%20s | %7d-%02d | %7d-%02d%n", "WeekFields",
date1.get(WeekFields.ISO.weekBasedYear()), date1.get(WeekFields.ISO.weekOfWeekBasedYear()),
date2.get(WeekFields.ISO.weekBasedYear()), date2.get(WeekFields.ISO.weekOfWeekBasedYear()));
}
}
以及相应的输出:
>java TestDate
Azul Systems, Inc.
1.8.0_282
==============
Locale.getDefault(.) | | DISPLAY | FORMAT
getDisplayLanguage | English | English | French
getDisplayCountry | United States | United States | France
getDisplayVariant | | |
getLanguage | en | en | fr
getCountry | US | US | FR
getVariant | | |
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 2 / 4
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2020-53 | 2020-53
WeekFields | 2020-53 | 2020-53
>java -Duser.language=en -Duser.country=US -Duser.variant= TestDate
Azul Systems, Inc.
1.8.0_282
==============
Locale.getDefault(.) | | DISPLAY | FORMAT
getDisplayLanguage | English | English | English
getDisplayCountry | United States | United States | United States
getDisplayVariant | | |
getLanguage | en | en | en
getCountry | US | US | US
getVariant | | |
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 1 / 1
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2021-01 | 2021-01
WeekFields | 2020-53 | 2020-53
我不明白 Talend ETL 的实施与您有什么关系。如果他们还没有找到升级到 java.time、现代 Java 日期和时间 API 的机会,那是他们的问题,而不是你的问题。您不应在自己的代码中使用 SimpleDateFormat
或 Calendar
。
Java 有 3 个默认语言环境
Java 不仅有一个,还有三个默认区域设置,部分原因是历史原因。它们可以单独设置。演示:
Locale.setDefault(Locale.FRANCE);
Locale.setDefault(Locale.Category.DISPLAY, Locale.JAPAN);
Locale.setDefault(Locale.Category.FORMAT, Locale.GERMANY);
System.out.println(Locale.getDefault());
System.out.println(Locale.getDefault(Locale.Category.DISPLAY));
System.out.println(Locale.getDefault(Locale.Category.FORMAT));
此片段的输出是:
fr_FR
ja_JP
de_DE
输出按顺序反映 F运行ce、日本和德国 (deutsch/Deutschland)。
您的评论指出 SimpleDateFormat
的代码使用默认的 FORMAT 语言环境作为其默认语言环境(在我的示例中是德国)。也就是说,当您未指定语言环境时它使用的语言环境(您不应使用 SimpleDateFormat
,如果您这样做,则应始终明确指定语言环境)。
我说了,三个可以单独设置。不过,单参数 Locale.setDefault()
设置了所有三个参数。
这个观察可以解释吗? 在我的 Java 11 上,似乎在命令行上设置区域设置会设置所有三个默认区域设置(直到被 Locale.setDefault()
).我刚试过
System.out.println(Locale.getDefault());
System.out.println(Locale.getDefault(Locale.Category.DISPLAY));
System.out.println(Locale.getDefault(Locale.Category.FORMAT));
我在命令行上 运行 这个片段 -Duser.language=en -Duser.country=US
,输出是:
en_US
en_US
en_US
其他语言和国家/地区设置也适用于所有三个区域。所以不,这并不能单独解释为什么你的 SimpleDateFormat
在一种情况下似乎没有从命令行获取语言环境。
这个观察是否提供了解决方案?
我还没有明白你真正的最终目标是什么。第一条建议是:您的代码不应依赖于 JVM 的默认语言环境。在区域设置敏感操作中使用显式区域设置。
如果您确实需要为 Talend ETL 设置默认格式区域设置以按照您要求的方式工作,Locale.setDefault(Locale.Category.FORMAT, Locale.US);
应该这样做。
Link
相关问题:Which "default Locale" is which?
我必须处理 SimpleDateFormat 但我对星期几值有疑问。
为了缩小问题的范围,我在下面编写了简单的 Java 代码,发现 returns 两个不同的结果具有明显相同的设置(只是通过在命令行上强制本地)。 问题仅出现在Windows(美国配置)机器上:如果我运行在Linux(CentOS)机器上进行相同的测试,一切正常。
Windows 上的 JVM 是 zulu8 1.8.0_282 openjdk(但似乎我与 oracle 8 jdk 的行为相同)而它是 Red Hat 1.8.0_272 在 Linux.
上打开 jdk这是源代码:
import java.util.Locale;
import java.util.Calendar;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
public class TestDate {
public static void main(String args[]) throws ParseException {
Locale currentLocale = Locale.getDefault();
System.out.println(System.getProperty("java.vendor"));
System.out.println(System.getProperty("java.version"));
System.out.println("==============");
System.out.printf("%20s = %s%n", "getDisplayLanguage", currentLocale.getDisplayLanguage());
System.out.printf("%20s = %s%n", "getDisplayCountry", currentLocale.getDisplayCountry());
System.out.printf("%20s = %s%n", "getDisplayVariant", currentLocale.getDisplayVariant());
System.out.printf("%20s = %s%n", "getLanguage", currentLocale.getLanguage());
System.out.printf("%20s = %s%n", "getCountry", currentLocale.getCountry());
System.out.printf("%20s = %s%n", "user.country", System.getProperty("user.country"));
System.out.printf("%20s = %s%n", "user.language", System.getProperty("user.language"));
System.out.printf("%20s = %s%n", "user.variant", System.getProperty("user.variant"));
System.out.println("==============");
Calendar c = Calendar.getInstance();
System.out.println("1st day of week / minimal days in 1st week : " + c.getFirstDayOfWeek() + " / " + c.getMinimalDaysInFirstWeek());
System.out.println("==============");
LocalDate date1 = LocalDate.of(2020, 12, 31);
LocalDate date2 = LocalDate.of(2021, 1, 1);
DateFormat df_date = new java.text.SimpleDateFormat("dd/MM/yyyy");
DateFormat df_week = new java.text.SimpleDateFormat("YYYY-ww");
System.out.printf("%20s | %10s | %10s%n", "", df_date.format(java.sql.Date.valueOf(date1)), df_date.format(java.sql.Date.valueOf(date2)));
System.out.printf("%20s | %10s | %10s%n", "SimpleDateFormat", df_week.format(java.sql.Date.valueOf(date1)), df_week.format(java.sql.Date.valueOf(date2)));
System.out.printf("%20s | %7d-%02d | %7d-%02d%n", "WeekFields",
date1.get(WeekFields.ISO.weekBasedYear()), date1.get(WeekFields.ISO.weekOfWeekBasedYear()),
date2.get(WeekFields.ISO.weekBasedYear()), date2.get(WeekFields.ISO.weekOfWeekBasedYear()));
}
}
这是结果(第二个是预期的):
>java TestDate
Azul Systems, Inc.
1.8.0_282
==============
getDisplayLanguage = English
getDisplayCountry = United States
getDisplayVariant =
getLanguage = en
getCountry = US
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 2 / 4
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2020-53 | 2020-53
WeekFields | 2020-53 | 2020-53
>java -Duser.language=en -Duser.country=US -Duser.variant= TestDate
Azul Systems, Inc.
1.8.0_282
==============
getDisplayLanguage = English
getDisplayCountry = United States
getDisplayVariant =
getLanguage = en
getCountry = US
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 1 / 1
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2021-01 | 2021-01
WeekFields | 2020-53 | 2020-53
两者似乎使用相同的语言环境设置,但 SimpleDateFormat returns 不同 week/year 周。 我是否缺少某些区域设置?
感谢您的帮助。
使用 Oracle JDK 编辑:
>java TestDate
Oracle Corporation
1.8.0_202
==============
getDisplayLanguage = English
getDisplayCountry = United States
getDisplayVariant =
getLanguage = en
getCountry = US
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 2 / 4
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2020-53 | 2020-53
WeekFields | 2020-53 | 2020-53
>java -Duser.language=en -Duser.country=US -Duser.variant= TestDate
Oracle Corporation
1.8.0_202
==============
getDisplayLanguage = English
getDisplayCountry = United States
getDisplayVariant =
getLanguage = en
getCountry = US
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 1 / 1
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2021-01 | 2021-01
WeekFields | 2020-53 | 2020-53
编辑日历默认区域设置:
正如 Scratte 所指出的,Calendar 和 SimpleDateFormat 使用默认的 Locale。我查看了 SimpleDateFormat source code,它使用 Locale.getDefault(Locale.Category.FORMAT)
作为默认 Local,这与我在代码中使用的 Locale.getDefault()
不同。
我终于明白了为什么我在两个代码之间有 2 个不同的行为:我没有显示正确的 Locale(我不知道 3 个不同的 Locale ;谢谢 Ole V.V。澄清这一点) .
TL;DR
SimpleDateFormat
使用 Locale.getDefault(Locale.Category.FORMAT)
而我的 Java 代码显示 Locale.getDefault()
的值。
后者总是 en_US
但前者是 fr_FR
或 en_US
取决于我使用的命令行。这就是为什么我每周/每年有两个不同的输出。
最后,JVM参数-Duser.language= / -Duser.country= / -Duser.variant=
是解决方案(它们强制所有三个不同的Locale)!
这段新代码显示了三种不同语言环境的区别:
import java.sql.Date;
import java.util.Locale;
import java.util.Calendar;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
public class TestDate {
public static void main(String args[]) throws ParseException {
Locale cL = Locale.getDefault();
Locale cLD = Locale.getDefault(Locale.Category.DISPLAY);
Locale cLF = Locale.getDefault(Locale.Category.FORMAT);
System.out.println(System.getProperty("java.vendor"));
System.out.println(System.getProperty("java.version"));
System.out.println("==============");
System.out.printf("%20s | %15s | %15s | %15s%n", "Locale.getDefault(.)", "", "DISPLAY", "FORMAT");
System.out.printf("%20s | %15s | %15s | %15s%n", "getDisplayLanguage", cL.getDisplayLanguage(), cLD.getDisplayLanguage(), cLF.getDisplayLanguage());
System.out.printf("%20s | %15s | %15s | %15s%n", "getDisplayCountry", cL.getDisplayCountry(), cLD.getDisplayCountry(), cLF.getDisplayCountry());
System.out.printf("%20s | %15s | %15s | %15s%n", "getDisplayVariant", cL.getDisplayVariant(), cLD.getDisplayVariant(), cLF.getDisplayVariant());
System.out.printf("%20s | %15s | %15s | %15s%n", "getLanguage", cL.getLanguage(), cLD.getLanguage(), cLF.getLanguage());
System.out.printf("%20s | %15s | %15s | %15s%n", "getCountry", cL.getCountry(), cLD.getCountry(), cLF.getCountry());
System.out.printf("%20s | %15s | %15s | %15s%n", "getVariant", cL.getVariant(), cLD.getVariant(), cLF.getVariant());
System.out.printf("%20s = %s%n", "user.country", System.getProperty("user.country"));
System.out.printf("%20s = %s%n", "user.language", System.getProperty("user.language"));
System.out.printf("%20s = %s%n", "user.variant", System.getProperty("user.variant"));
System.out.println("==============");
Calendar c = Calendar.getInstance();
System.out.println("1st day of week / minimal days in 1st week : " + c.getFirstDayOfWeek() + " / " + c.getMinimalDaysInFirstWeek());
System.out.println("==============");
LocalDate date1 = LocalDate.of(2020, 12, 31);
LocalDate date2 = LocalDate.of(2021, 1, 1);
DateFormat df_date = new java.text.SimpleDateFormat("dd/MM/yyyy");
DateFormat df_week = new java.text.SimpleDateFormat("YYYY-ww");
System.out.printf("%20s | %10s | %10s%n", "", df_date.format(java.sql.Date.valueOf(date1)), df_date.format(java.sql.Date.valueOf(date2)));
System.out.printf("%20s | %10s | %10s%n", "SimpleDateFormat", df_week.format(java.sql.Date.valueOf(date1)), df_week.format(java.sql.Date.valueOf(date2)));
System.out.printf("%20s | %7d-%02d | %7d-%02d%n", "WeekFields",
date1.get(WeekFields.ISO.weekBasedYear()), date1.get(WeekFields.ISO.weekOfWeekBasedYear()),
date2.get(WeekFields.ISO.weekBasedYear()), date2.get(WeekFields.ISO.weekOfWeekBasedYear()));
}
}
以及相应的输出:
>java TestDate
Azul Systems, Inc.
1.8.0_282
==============
Locale.getDefault(.) | | DISPLAY | FORMAT
getDisplayLanguage | English | English | French
getDisplayCountry | United States | United States | France
getDisplayVariant | | |
getLanguage | en | en | fr
getCountry | US | US | FR
getVariant | | |
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 2 / 4
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2020-53 | 2020-53
WeekFields | 2020-53 | 2020-53
>java -Duser.language=en -Duser.country=US -Duser.variant= TestDate
Azul Systems, Inc.
1.8.0_282
==============
Locale.getDefault(.) | | DISPLAY | FORMAT
getDisplayLanguage | English | English | English
getDisplayCountry | United States | United States | United States
getDisplayVariant | | |
getLanguage | en | en | en
getCountry | US | US | US
getVariant | | |
user.country = US
user.language = en
user.variant =
==============
1st day of week / minimal days in 1st week : 1 / 1
==============
| 31/12/2020 | 01/01/2021
SimpleDateFormat | 2021-01 | 2021-01
WeekFields | 2020-53 | 2020-53
我不明白 Talend ETL 的实施与您有什么关系。如果他们还没有找到升级到 java.time、现代 Java 日期和时间 API 的机会,那是他们的问题,而不是你的问题。您不应在自己的代码中使用 SimpleDateFormat
或 Calendar
。
Java 有 3 个默认语言环境
Java 不仅有一个,还有三个默认区域设置,部分原因是历史原因。它们可以单独设置。演示:
Locale.setDefault(Locale.FRANCE);
Locale.setDefault(Locale.Category.DISPLAY, Locale.JAPAN);
Locale.setDefault(Locale.Category.FORMAT, Locale.GERMANY);
System.out.println(Locale.getDefault());
System.out.println(Locale.getDefault(Locale.Category.DISPLAY));
System.out.println(Locale.getDefault(Locale.Category.FORMAT));
此片段的输出是:
fr_FR ja_JP de_DE
输出按顺序反映 F运行ce、日本和德国 (deutsch/Deutschland)。
您的评论指出 SimpleDateFormat
的代码使用默认的 FORMAT 语言环境作为其默认语言环境(在我的示例中是德国)。也就是说,当您未指定语言环境时它使用的语言环境(您不应使用 SimpleDateFormat
,如果您这样做,则应始终明确指定语言环境)。
我说了,三个可以单独设置。不过,单参数 Locale.setDefault()
设置了所有三个参数。
这个观察可以解释吗? 在我的 Java 11 上,似乎在命令行上设置区域设置会设置所有三个默认区域设置(直到被 Locale.setDefault()
).我刚试过
System.out.println(Locale.getDefault());
System.out.println(Locale.getDefault(Locale.Category.DISPLAY));
System.out.println(Locale.getDefault(Locale.Category.FORMAT));
我在命令行上 运行 这个片段 -Duser.language=en -Duser.country=US
,输出是:
en_US en_US en_US
其他语言和国家/地区设置也适用于所有三个区域。所以不,这并不能单独解释为什么你的 SimpleDateFormat
在一种情况下似乎没有从命令行获取语言环境。
这个观察是否提供了解决方案?
我还没有明白你真正的最终目标是什么。第一条建议是:您的代码不应依赖于 JVM 的默认语言环境。在区域设置敏感操作中使用显式区域设置。
如果您确实需要为 Talend ETL 设置默认格式区域设置以按照您要求的方式工作,Locale.setDefault(Locale.Category.FORMAT, Locale.US);
应该这样做。
Link
相关问题:Which "default Locale" is which?