Java-world apporach to localization - 有任何暗示吗?

时间:2017-08-28 08:53:03

标签: java localization internationalization formatting jvm

在.NET中CurrentCultureCurrentUICulture属性在很多情况下都是隐式使用的 例如,在ToString()值上调用DateTime将根据当前用户的区域设置格式化日期和时间。

相反,Java的LocalDate.toString()具有固定的格式,除非明确使用了formatter。

因此,有一个问题:

除非开发人员明确指定,否则Java是否会避免对语言环境的隐式依赖并具有一些固定的格式?我应该担心这种隐含吗?

1 个答案:

答案 0 :(得分:2)

toString不用于演示

大多数类的toString方法实现意味着对象值的文本表示,用于调试和记录,而不是在用户界面中显示。 toString方法在Java中所有类的根超类中定义:Object::toString()

java.time中的toString实现使用标准ISO 8601格式。这些可能适合您的用户,也可能不适合您,具体取决于受众。请注意,将日期时间值序列化为文本以存储/交换数据流时,ISO 8601格式是理想的。

java.time format方法

要向用户演示,通常使用toString以外的方法。

java.time框架具有format方法的约定,您可以将DateTimeFormatter对象传递给它。通过调用静态因子ofLocalized…方法,可以使该格式化程序自动进行本地化。

ZonedDateTime示例

ZoneId z = ZoneId.of( "America/Montreal" ) ;
// Better to specify time zone explicitly than rely on the default implicitly.
ZonedDateTime zdt = ZonedDateTime.now( z ) ;  
FormatStyle s = FormatStyle.LONG ; 
Locale l = Locale.CANADA_FRENCH ;
// Better to specify locale explicitly than rely on the default implicitly.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( s ).withLocale( l ) ; 
String output = zdt.format( f ) ;
  

输出:28août2017à16:28:00 EDT

     

zdt.toString():2017-08-28T16:28:00.107907-04:00 [美国/蒙特利尔]

请注意ZonedDateTime::toString明智地扩展了ISO 8601格式,方法是在方括号中附加时区名称。

LocalDate示例

至于您的LocalDate问题,我们可以从ZonedDateTime中提取仅限日期的值。

LocalDate ld = zdt.toLocalDate() ;
DateTimeFormatter f2 = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( l  );
String output2 = ld.format( f2 );
  

output2:lundi 28août2017

     

ld.toString():2017-08-28

隐式默认值

对于隐式默认值,是的,如果您未指定,则java.time类将隐式使用JVM的当前默认值Locale。同上时区。

我建议养成始终明确指定的习惯,如上面的代码示例所示。两者都可以在运行时(!)中由该JVM中运行的任何应用程序的任何线程中的任何代码进行更改。因此,依赖默认值是不可靠的。

避免遗留日期时间类

仅供参考,java.time取代的旧版日期时间类设计很差,包括一些松散的格式化选择。 将这些作为正确设计的指导。