我正在使用DateTimeFormatter格式化日期:
ZonedDateTime date = ZonedDateTime.parse("2015-12-03T18:15:30+01:00[America/New_York]");
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL)
.withLocale(Locale.FRENCH);
System.out.println(formatter.format(date));
代码输出:
jeudi 3 décembre 2015 18 h 15 EST
如何将时区从EST转换为法语HNE(Heure Normale de l'Est)?
任何帮助将不胜感激。
答案 0 :(得分:3)
➥升级到Java 8以上。
使用CLDR的Java 9和更高版本现在在某些语言环境中表现出不同的本地化行为。
在Java 8中运行代码将显示观察到的结果jeudi 3 décembre 2015 18 h 15 EST
,而在Java 9和更高版本中运行将显示您期望的结果jeudi 3 décembre 2015 à 18:15:30 heure normale de l’Est nord-américain
。
我按原样尝试了您的代码,但var名称除外。
System.out.println( System.getProperty( "java.version" ) );
ZonedDateTime zdt = ZonedDateTime.parse( "2015-12-03T18:15:30-05:00[America/New_York]" );
DateTimeFormatter formatter =
DateTimeFormatter
.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( Locale.FRENCH );
System.out.println( formatter.format( zdt ) );
结果:
10.0.2
jeudi 3décembre2015à18:15:30 heure normale de l’Estnord-américain
但是您声称看到了这个结果:
jeudi 3décembre2015 18 h 15 EST
为什么有区别?
好吧,我正在运行Java10。让我们尝试Java 8。
1.8.0_181
jeudi 3décembre2015 18 h 15 EST
啊哈!现在,我看到了您的结果。
顺便说一句,您的示例数据"2015-12-03T18:15:30+01:00[America/New_York]"
与discovered by Meno Hochschild一样,对区域+01:00
使用了不正确的UTC偏移量America/New_York
。应该是-05:00
。我更正了您在此答案中使用的字符串。请参阅Answer by Hochschild,以获取更多讨论。
我怀疑差异是由于Java 9的重大变化,至少是基于Java 9的基于OpenJDK的实现。在Java 9中,OpenJDK从使用其自己的本地化数据定义切换为从{{ 3}} Unicode Consortium。参见Common Locale Data Repository (CLDR)。
在提供的多种数据中,有“时区的翻译以及时区的示例城市(或类似城市)”。
所以没有错误,没有问题。本地化是一个复杂的过程,其中对于适当的选择通常会有不止一种意见。您发现了一个示例,其中与OpenJDK 8捆绑在一起的本地化数据的作者以及更早版本的人与Unicode联盟的作者不同意。也许文化规范随着时间的流逝而改变。
CLDR的一大优点是,除了具有更丰富的语言环境数据集之外,CLDR是语言环境数据的事实上标准来源。 CLDR已被许多其他系统采用。因此,现在Java应用程序将表现出与其他系统相同的行为,或者几乎具有相同的行为,但由于版本控制可能会有所不同。
谈到版本控制,(希望)对于大多数语言环境而言,更改的可能性不大,因为Unicode联盟已为此努力了很多年。如今,CLDR应该相对完整和稳定。正如从本课题中看到的那样,虽然一些Java应用程序从Java <= 8跳到Java> = 9可能会看到行为上的一些重大变化,但继续前进,您应该会发现很少的惊喜/变化。
注意事项::这里的整个讨论都与基于JEP 252: Use CLDR Locale Data by Default的Java实现有关。如今,这意味着大多数供应商(Azul,AdoptOpenJDK.net,Amazon Corretto,IBM,Oracle JDK和Oracle构建的OpenJDK)。但是,不是从OpenJDK构建的任何Java实现都可以自由使用CLDR以外的其他本地化数据和行为源。
CLDR实际上是OpenJDK,但默认情况下不使用。 OpenJDK 9和更高版本中的更改是,默认情况下将CLDR提升为included in OpenJDK 8, per JEP 127。请参见first locale data provider consulted, per JEP 252,使CLDR在8中成为主要的语言环境数据提供者。
提示:在指定语言环境时,尽量避免仅使用“ FRENCH”。语言环境是人类语言加的国家/地区代码的组合,代表一组文化规范,确定了诸如大写,缩写,元素排序(例如:年-月-日)之类的问题。 。尽管Locale.FRENCH
可能会回到使用法国这样的国家/地区,但我建议您明确一点。例如,使用Locale.FRANCE
或Locale.CANADA_FRENCH
。
要使用少数Java常量中未定义的数百种语言和国家/地区代码,请使用已记录的标准字符串代码。例如,fr-FR
代表法国的法语。
此外,请注意,CLDR具有更详细,细微差别的语言环境信息,因此您现在可以选择使用未在定义中定义的许多变体和扩展名(基本上是国家文化内的亚文化)。旧的语言环境数据集。有关更多信息,请参见Answer by Meno Hochschild和Unicode Consortium网站。
答案 1 :(得分:2)
到目前为止,给出的问题和其他答案仅集中在区域名称翻译的主题上。但是主要问题是解析的时间错误。现在让我们进入细节。
固定偏移量(UTC + 01)和区域标识符“ America / New_York”的组合有点奇怪,因为由“ America / New_York”标识的区域仅知道偏移量UTC-05(和UTC-夏季04)。
此类矛盾和矛盾的组合应优先考虑偏移量进行解析。因此,时间“ 2015-12-03T18:15:30 + 01:00”与“ 2015-12-03T12:15:30-05:00”是同一时刻,但您仍然解析了相同的本地时间“ 18 :15:30“在EST区域(偏移UTC-05),这是一个严重错误。关联的JDK-Bug已解决,但仅适用于Java 9+,尚未解决的Java-8 backport。
关于翻译的主题,Basil Bourque说了一些有关将CLDR数据引入Java 9及以后的标准/默认设置的正确信息。可以在Java-8中通过setting the system property将默认存储库更改为“ java.locale.providers = CLDR,JRE”。 此配置可能会解决Java-8的翻译问题,但解析时间错误的另一个问题仍然存在。
答案 2 :(得分:0)
您必须在Oracle公司定义的全局区域中使用合适的区域。 TimeZone.getAvailableIDs()
可用于以String
数组查看所有可用时区。根据您的要求,您可以使用Europe/Paris
时区。定义具有新时区的新日期,而不更改日期,如下所示,
ZonedDateTime dateParis =
date.withZoneSameLocal( ZoneId.of( "Europe/Paris" ) );
有关更多详细信息,请参阅以下链接 https://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html#getAvailableIDs%28%29 https://garygregory.wordpress.com/2013/06/18/what-are-the-java-timezone-ids/ https://dzone.com/articles/deeper-look-java-8-date-and