如何显示正确的本地化DateTime格式?

Soh*_*eil 2 java datetime datetime-format

我正在编写一个JavaFx程序,显示Windows的时间和日期格式.这意味着当我更改Windows的语言时,程序应该显示新的时间和日期格式.例如,在某些位置,时间格式如下:

二○一八年十二月三十零日

在其他位置,它显示如下:

二○一八年十二月三十零日

我尝试使用Java中的LocalDateTime类,但这没有任何意义,因为该类没有时区信息.

private void init()
{
    button = new Button("Update");
    button.setFont(Font.font(null,FontWeight.BOLD,15));
    setBottom(button);
    setAlignment(button, Pos.CENTER);
    setPadding(new Insets(15));

    ldt = LocalDateTime.now();
    label = new Label();
    label.setFont(Font.font(null, FontWeight.BOLD,20));
    label.setTextFill(Color.RED);
    label.setAlignment(Pos.CENTER);

    text = ldt.toString();
    label.setText(text);

    gridPane = new GridPane();
    gridPane.add(label, 0, 0);
    gridPane.setAlignment(Pos.CENTER);
    setCenter(gridPane);        
}
Run Code Online (Sandbox Code Playgroud)

德语:

在此输入图像描述

英语:

在此输入图像描述

如何正确显示?

Bas*_*que 7

错误的课程: LocalDateTime

永远不要LocalDateTime用来追踪实际时刻.缺乏任何时区概念或从UTC偏移,a LocalDateTime不能代表片刻.一LocalDateTime可以知道"在2019 1月23日中午",但它并不会知道,如果你在日本东京,中午在突尼斯突尼斯,或中午蒙特利尔魁北克是说中午-三个非常不同的时刻,每个都由几个小时分开.

"本地"一词LocalDateTime表示任何地点或每个地点.但这并不意味着任何一个特定地区.

正确的课程: ZonedDateTime

要跟踪时刻,请使用Instant(始终以UTC格式)或ZonedDateTime(或许OffsetDateTime).

指定适当的时区名称,格式Continent/Region,如America/Montreal,Africa/CasablancaPacific/Auckland.切勿使用2-4字母缩写,例如ESTIST因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment as seen through the wall-clock time used by the people of a particular region (a time zone). 
Instant instant = zdt.toInstant() ;  // Adjust from a zone to UTC, if needed. An `Instant` is always in UTC by definition. 
Run Code Online (Sandbox Code Playgroud)

如果未指定时区,则JVM会隐式应用其当前的默认时区.该默认值可能会在运行时(!)期间随时更改,因此您的结果可能会有所不同.最好明确指定您期望/预期的时区作为参数.如果关键,请与您的用户确认该区域.

自动本地化

DateTimeFormatter同时生成表示日期时间对象的值的文本类可自动定位.

要进行本地化,请指定:

  • FormatStyle 确定字符串的长度或缩写.
  • Locale 确定:
    • 用于翻译日期名称,月份名称等的人类语言.
    • 文化规范决定的缩写,大小写,标点符号,分离器,和这样的问题.

例:

Locale l = Locale.CANADA_FRENCH ;   // Or Locale.US, Locale.JAPAN, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL )
                                       .withLocale( l );
String output = zdt.format( f );
Run Code Online (Sandbox Code Playgroud)

要明确的是,语言环境和时区彼此无关 - 正交问题.来自魁北克的一位工程师在印度参加一个会议,可能希望看到以加拿大文化规范用她的母语法语表示的活动时间表,以及印度当地时区显示的日期时间.


关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

现在处于维护模式Joda-Time项目建议迁移到java.time类.

您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.

  • 这是一个很好的答案,我希望有一种方法可以让它得到更多的关注,而不是埋没在一些随机问题中. (2认同)
  • @Basil请注意,人们正在谈论你的答案,这些答案可能会吸引元效应投票,而且一般的共识似乎是针对你在多个帖子中添加相同的样板文本.https://meta.stackoverflow.com/questions/380536/same-aside-added-to-the-end-of-multiple-answers?cb=1 (2认同)