【问题标题】:to display local date/time for different countries in java在java中显示不同国家的本地日期/时间
【发布时间】:2019-11-26 09:58:00
【问题描述】:

我必须在 java 中显示不同国家/地区的本地日期时间。目前我正在为“America/New_York”设置 zoneId,因此只获取服务器上所有地方的 EST 时间。如何动态实现本地日期/时间。

DateTimeFormatter globalFormat = DateTimeFormatter.ofPattern("dd-MMM-yyyy hh:mm a z");
DateTimeFormatter estFormat = DateTimeFormatter.ofPattern("dd-MMM-yyyy hh:mm a 'EST'");
ZoneId istZoneId = ZoneId.of("Asia/Calcutta");
ZoneId estZoneId = ZoneId.of("America/New_York");

Instant instant = Instant.now() ;
ZonedDateTime zdt = ZonedDateTime.now( estZoneId) ;
ZonedDateTime currentISTime = instant.atZone(istZoneId);                //India time
ZonedDateTime currentESTime = zdt.withZoneSameInstant(estZoneId);       //EST Time         

System.out.println("est time.............."+estFormat.format(currentESTime)); 

【问题讨论】:

  • 这段代码是在不同机器上不同区域执行还是后端代码和前端可以定义本地/时区?
  • 是的,这段代码在不同区域的不同机器上执行,它是一个后端代码。前端没有定义任何时区。
  • 您是否尝试过仅获取 UTC 日期时间并在何时/根据需要进行转换?您也可以直接使用系统默认时区:ZonedDateTime zdt = ZonedDateTime.now(ZoneId.systemDefault());
  • 你已经在那里了。如果您打印currentISTime,会发生什么?只是不要在格式化程序中硬编码EST。使用模式字母zzz 打印适当的时区缩写。

标签: java zoneddatetime


【解决方案1】:

利用ZoneId.systemDefault():

public static void main(String[] args) {
    // take the instant
    Instant instant = Instant.now();
    // use it in system default time zone
    ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
    // then in Asia/Calcutta
    ZonedDateTime currentISTime = instant.atZone(ZoneId.of("Asia/Calcutta"));
    // and in America/New York
    ZonedDateTime currentESTime = zdt.withZoneSameInstant(ZoneId.of("America/New_York"));
    // then print them all using the ISO format for zoned date times
    System.out.println("System default:\t" + zdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    System.out.println("EST:\t\t" + currentISTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    System.out.println("IST:\t\t" + currentESTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}

在我的系统上,打印出来

System default: 2019-11-26T12:19:18.865+01:00[Europe/Berlin]
EST:            2019-11-26T16:49:18.696+05:30[Asia/Calcutta]
IST:            2019-11-26T06:19:18.865-05:00[America/New_York]

找出它对您和其他相关产品的作用。 这完全是动态的,它依赖于系统默认值(在某些情况下可能会被操纵)。

【讨论】:

    【解决方案2】:

    确实,如果您将您的区域定义为 EST,这就是您将始终显示的日期。事实上,仅现在使用Instant.now() 或任何 Date 类是一种不好的做法。要么你传递一个ZoneId,要么你想泛化你使用Clock

    但是能够根据您所在的位置更改区域也是一种不好的做法。您应该始终(在后端应用程序中)使用 UTC 日期作为输出和输入,因此使用以下内容定义时钟:

    @Configuration
    public class ClockConfiguration {
    
        @Bean
        public Clock domainClock() {
            return Clock.systemUTC();
        }
    
    }
    

    然后您可以在需要的地方注入时钟并使用Instant.now(clock)

    但前端应该负责在用户时区显示日期,因此您应该只在应用程序中使用 UTC 日期。

    如果您真的想根据位置在每个服务器上定义不同的时钟(我真的不建议这样做!!),您可以在代码中对每个日期对象使用 .now() 方法并更改物理服务器把它放在想要的时区。现在将使用服务器的本地时区,它应该可以工作,然后删除代码中对区域的所有使用(尽管它可能会导致数据库中出现严重错误,因为日期最终会发生冲突)。

    【讨论】:

      【解决方案3】:

      ZoneIdZonedDateTime 是你想要的。

      ZoneId zoneId = ZoneId.systemDefault();
      Locale locale = Locale.getDefault();
      

      您可以提供一个开关,这对开发也很有用:

      Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
      Locale[] availabelLocales = Locale.getAvailableLocales();
      

      有时可能需要添加您自己的语言环境,尤其是对于小国家或世界语。这需要一些努力。

      默认使用ZonedDateTime

      ZonedDateTime zdt = ZonedDateTime.now();
      

      本地化的日期/时间/日期时间格式:DateTimeFormatter:

      DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG).withLocale(Locale.FRANCE);
      

      withLocale 如果您想使用特定的语言环境。)

      不用说全部存储为通用协调时间、Z 或ZoneId.of("UTC")

      【讨论】:

        猜你喜欢
        • 2020-05-22
        • 1970-01-01
        • 1970-01-01
        • 2012-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-09
        • 2021-07-12
        相关资源
        最近更新 更多