有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

zoneddatetime可在java中显示不同国家/地区的本地日期/时间

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

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)); 

共 (3) 个答案

  1. # 1 楼答案

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

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

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

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

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

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

  2. # 2 楼答案

    利用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]
    

    看看它对你和其他相关的人有什么影响。 通过依赖系统默认值(在某些情况下可能会被操纵),这是非常动态的

  3. # 3 楼答案

    ^{}ZonedDateTime是你想要的

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

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

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

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

    默认情况下使用ZonedDateTime

    ZonedDateTime zdt = ZonedDateTime.now();
    

    本地化的日期/时间/日期-时间格式:^{}

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

    withLocale应该使用特定的语言环境。)

    不用说,将所有数据存储为通用协调时间Z或ZoneId.of("UTC")