在.NET中CurrentCulture
和CurrentUICulture
属性在很多情况下都是隐式使用的
例如,在ToString()
值上调用DateTime
将根据当前用户的区域设置格式化日期和时间。
相反,Java的LocalDate.toString()
具有固定的格式,除非明确使用了formatter。
因此,有一个问题:
除非开发人员明确指定,否则Java是否会避免对语言环境的隐式依赖并具有一些固定的格式?我应该担心这种隐含吗?
答案 0 :(得分:2)
toString
不用于演示大多数类的toString
方法实现意味着对象值的文本表示,用于调试和记录,而不是在用户界面中显示。 toString
方法在Java中所有类的根超类中定义:Object::toString()
。
java.time中的toString
实现使用标准ISO 8601格式。这些可能适合您的用户,也可能不适合您,具体取决于受众。请注意,将日期时间值序列化为文本以存储/交换数据流时,ISO 8601格式是理想的。
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取代的旧版日期时间类设计很差,包括一些松散的格式化选择。 不将这些作为正确设计的指导。