简体   繁体   English

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

[英]to display local date/time for different countries in java

I have to display local date time for different countries in java.Currently I am setting zoneId for "America/New_York" and so only getting EST time for all the places on the server.How to achieve local date/time dynamically. 我必须在java中显示不同国家/地区的本地日期时间。当前,我将zoneId设置为“ America / New_York”,因此只能获取服务器上所有位置的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)); 

Make use of ZoneId.systemDefault() : 利用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));
}

On my system, this prints 在我的系统上,此打印

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]

Find out what it does on yours and the remaining related ones. 找出对您和其余相关人员有何影响。 That's quite dynamical by relying on the system default (which may be manipulated under circumstances). 依靠系统默认值(在某些情况下可以操纵)是非常动态的。

Indeed if you define your zone as EST, this is the date you will always display. 确实,如果将区域定义为EST,则这是您将始终显示的日期。 In fact it is a bad practice to use Instant.now() or any Date classes with only now. 实际上,仅在现在才使用Instant.now()或任何Date类是一个不好的做法。 Either you pass a ZoneId as you do, or if you want to generify you use a Clock . ZoneId像做的那样传递ZoneId ,或者如果要泛化则使用Clock

But to be able to change the zone depending on where you are is also a bad practice. 但是,根据您所在的位置更改区域也是一种不好的做法。 You should always (in backend applications) use UTC dates, as outputs and inputs, and so define a Clock with something like this: 您应该始终(在后端应用程序中)使用UTC日期作为输出和输入,并使用以下方式定义Clock:

@Configuration
public class ClockConfiguration {

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

}

You could then inject the clock where needed and use Instant.now(clock) . 然后,您可以在需要的地方注入时钟,并使用Instant.now(clock)

But it should be of the responsibility of the frontend to display the date on the user timezone, and so you should only use UTC dates in your application. 但是前端应负责在用户时区上显示日期,因此您应仅在应用程序中使用UTC日期。

If you really wanted to define a different clock on each of your server depending on their location (which I really not advise!!) you can in your code use .now() method on every date object and change the zone of the physical server to put it in the wanted timezone. 如果您真的想根据服务器的位置在每个服务器上定义不同的时钟(我真的不建议!),则可以在代码中对每个日期对象使用.now()方法,并更改物理服务器的区域将其放在所需的时区。 The now would then use the local timezone of the server and it should work, and then remove every use of zone in your code (although it could lead to terrible mistakes in your database as date would eventually conflicts). 然后,现在将使用服务器的本地时区,它应该可以工作,然后删除代码中对时区的所有使用(尽管由于日期最终会冲突,这可能导致数据库中的严重错误)。

ZoneId with ZonedDateTime is what you want. ZoneIdZonedDateTime是你想要的。

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

You could offer a switch, which is useful for development too: 您可以提供一个开关,这对于开发也很有用:

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

Adding your own Locale might sometimes be required, especially for small countries or Esperanto. 有时可能需要添加您自己的语言环境,尤其是对于小国或世界语。 It requires some effort. 这需要一些努力。

Usage of ZonedDateTime for the default: 默认使用ZonedDateTime

ZonedDateTime zdt = ZonedDateTime.now();

A localized date/time/date-time formatting: DateTimeFormatter : 本地化的日期/时间/日期时间格式: DateTimeFormatter

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

( withLocale should you want to use a specific locale.) (如果要使用特定的语言环境,请使用withLocale 。)

Needless to say store all as universal coordinated time, Z, or ZoneId.of("UTC") . 不用说,所有都存储为通用协调时间Z或ZoneId.of("UTC")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM