Bas*_*que 23
区域设置和时区是与日期时间处理相关的单独的正交问题.
Monday还是Lundi?month-date-year,date-month-year或year-month-date?从长远来看,一周中的哪一天是第一位的吗?月份名称是初始上限还是全部小写?缩写是否具有FULL STOP(PERIOD)字符?因此,您可以混合使用区域设置和时区.一些例子如下.
Europe/Helsinki到America/Los_Angeles(西雅图时区).解析/生成作为日期时间值的文本表示的字符串时,仅在以下两种情况下使用Locale:
在第一种情况下,如果您的字符串包含"Monday"/"Lundi"或"March"/"Mars"等字词,则使用Locale来翻译这些字符串.
在第二种情况下,如果您没有明确的格式设置模式,则使用区域设置以了解星期几,日期,月份名称,年份等部分的预期顺序. .例如,说英语的美国人说"十一月十一日",讲法语的加拿大人使用逆序"11 octobre".通过软编码,我们的意思是类似于DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL )硬编码格式DateTimeFormatter.ofPattern("yyyy MM dd, EEE")
那么什么时候不需要Locale?如果您有一个包含所有数字的输入字符串,例如"2015-01-23",并且您将格式硬编码为"yyyy-MM-dd"...
String input = "2015-01-23";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd")
Run Code Online (Sandbox Code Playgroud)
......然后Locale实际上是无关紧要的.你无法翻译,没有"星期一"或"伦迪".并且不要求使用需要区域设置的本地化格式化程序来了解日期是在月份之前还是之后,以及其他此类详细信息.
请注意,您仍然可以在这种情况下指定区域设置.实际上,我建议你养成总是指定Locale(和时区)的习惯.
那么为什么你在没有任何语言环境的StackOverflow上看到这么多与日期时间相关的问题和答案呢?因为如果省略,JVM的当前默认语言环境将自动且无提示地应用.
因此,如果您在JVM上运行英文文本的字符串设置为美国语言环境,那么没问题.但是不推荐这种对隐式语言环境的依赖.如果在运行时调用期间任何应用程序的任何线程中的任何代码Locale.setDefault,并影响该JVM中的所有其他代码.然后你的代码抛出异常.最好养成明确指定预期/期望区域设置的习惯.
时区的建议相同.如果省略,则会自动且无提示地应用JMV的当前默认时区.同样,运行时期间任何应用程序的任何线程中的任何代码都可以调用TimeZone.setDefault,并影响该JVM中的所有其他代码.然后您的代码抛出异常或意外行为.
在运行时的惊喜变化应该是足够的理由,养成始终指定语言环境和时区的习惯.但另一个好处是它还使您的代码自我记录.此外,在编程时有意识地指定区域设置和时区可能会提醒您错误或未经证实的假设.
想象一下魁北克的商人.她向土耳其的一位客户确认他将在中午时分发货.因此,她使用壁挂时间创建一个物体,在土耳其接受交付.
ZoneId zoneIdIstanbul = ZoneId.of( "Europe/Istanbul" );
ZonedDateTime zdtIstanbul = ZonedDateTime.of( 2015, 10, 11, 12, 30, 00, 0, zoneIdIstanbul ); // Half-past noon in Turkey.
Run Code Online (Sandbox Code Playgroud)
为方便客户,她使用土耳其语和海关格式化文本.她定义了一个格式化程序对象来处理日期时间值的文本表示的生成.我们还可以在生成文本表示时为要应用的格式化程序分配时区.但是ZonedDateTime对象已经分配了时区,因此格式化程序将在该时区上进行拾取.
Locale locale_tr_TR = new Locale( "tr", "TR" );
DateTimeFormatter formatter_tr_TR = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( locale_tr_TR );
String outputTurkish = formatter_tr_TR.format( zdtIstanbul );
Run Code Online (Sandbox Code Playgroud)
我们的商人知道客户在芬兰使用物流协调员,所以她用芬兰语打印相同的日期时间值.所以我们有一个芬兰语区域的土耳其时区.
Locale locale_fi_FI = new Locale( "fi", "FI" );
DateTimeFormatter formatter_fi_FI = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( locale_fi_FI );
String outputFinnish = formatter_fi_FI.format( zdtIstanbul );
Run Code Online (Sandbox Code Playgroud)
对于她自己来说,她需要一个在自己的墙上时间预期交付的字符串,这样她就可以设置警报以提醒她检查成功完成.她本地读法语,而不是土耳其语.
所以下一个代码的不同之处在于我们需要调整时区和语言环境.时间轴中的相同时刻,即预期交付的日期时间,但在文本中表示不同.注意这次我们如何withZone在链的末尾添加一个额外的调用来创建一个格式化程序,我们指定一个时区调整来覆盖ZonedDateTime对象的指定区域.
Locale locale_fr_CA = Locale.CANADA_FRENCH;
ZoneId zoneId_Montréal = ZoneId.of( "America/Montreal" );
DateTimeFormatter formatter_fr_CA_Adjusted = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( locale_fr_CA ).withZone( zoneId_Montréal );
String outputQuébec = formatter_fr_CA_Adjusted.format( zdtIstanbul );
Run Code Online (Sandbox Code Playgroud)
最后,为了我们讲英语的StackOverflow.com读者,让我们用英语做一个版本.但请注意,我们回收魁北克格式化程序,保留已设置的时区,但将区域设置替换为美国的区域设置.(技术上不是回收,但可以这么说.使用不可变对象意味着使用基于旧对象的值来实例化新对象.)
Locale locale_en_US = Locale.US;
DateTimeFormatter formatter_US_Unadjusted = formatter_fr_CA_Adjusted.withLocale( locale_en_US );
String output_US_Unadjusted = formatter_US_Unadjusted.format( zdtIstanbul );
Run Code Online (Sandbox Code Playgroud)
让我们看看这些值的输出.转储到控制台.
首先,我们隐式调用对象toString上的方法ZonedDateTime.默认情况下,此方法使用ISO 8601定义的标准格式之一.但是java.time通过在方括号中附加时区的名称来扩展该格式[Europe/Istanbul].在交换数据时,请使用这些明确的标准格式,而不是任何更人性化的格式.
System.out.println( "zdtIstanbul : " + zdtIstanbul );
System.out.println( "outputTurkish : " + outputTurkish );
System.out.println( "outputFinnish : " + outputFinnish );
System.out.println( "outputQuébec : " + outputQuébec );
System.out.println( "output_US_Unadjusted : " + output_US_Unadjusted );
Run Code Online (Sandbox Code Playgroud)
输出结果告诉我们,土耳其的午餐时间表示我们在魁北克省的女士发出的凌晨5:30的警报.
zdtIstanbul : 2015-10-11T12:30+03:00[Europe/Istanbul]
outputTurkish : 11 Ekim 2015 Pazar 12:30:00 EEST
outputFinnish : sunnuntai, 11. lokakuuta 2015 12.30.00 EEST
outputQuébec : dimanche 11 octobre 2015 5 h 30 EDT
output_US_Unadjusted : Sunday, October 11, 2015 5:30:00 AM EDT
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2900 次 |
| 最近记录: |