Search code examples
javadateformat

Format a local date at another time zone


I try to format the current time in 2 locations: Chicago and Tokyo

LocalDateTime now = LocalDateTime.now();
ZonedDateTime chicago = now.atZone(ZoneId.of("America/New_York"));
System.out.println("chicago: " + chicago);
System.out.println("Chicago formated: " + chicago.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));

ZonedDateTime tokyo = now.atZone(ZoneId.of("Asia/Tokyo"));
System.out.println("Tokyo: " + tokyo);
System.out.println("Tokyo formated: " + tokyo.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));

The print out:

chicago: 2017-11-05T18:19:01.441-05:00[America/New_York]
Chicago formated: 6:19:01 PM EST
Tokyo: 2017-11-05T18:19:01.441+09:00[Asia/Tokyo]
Tokyo formated: 6:19:01 PM JST

6:19:01 PM printed for both Chicago and Tokyo. Why?

Thanks Andreas for make the above code work. Following your logic I try to make this work:

LocalDateTime PCTime = LocalDateTime.now();//Chicago: 7:51:54 PM
ZonedDateTime newYorkTime = PCTime.atZone(ZoneId.of("America/New_York"));
System.out.println("now: " + newYorkTime);
System.out.println("now fmt: " + newYorkTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));
ZonedDateTime newYorkTime0 = newYorkTime.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println("N.Y. fmt: " + newYorkTime0.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));

The output:

now: 2017-11-05T19:51:54.940-05:00[America/New_York]
now fmt: 7:51:54 PM EST
N.Y. fmt: 7:51:54 PM EST

The last line should be N.Y. fmt: 8:51:54 PM EST


Solution

  • LocalDateTime.atZone() means: Take this local time and consider it to be the local time in this time zone.

    That means that 6:19 PM "local time" in Chicago is ... 6:19 PM in time zone EST, and that 6:19 PM "local time" in Tokyo is ... 6:19 PM in time zone JST.

    When you call LocalDateTime.now(), you get the local time in your current default time zone, but the returned value don't know what time zone that is. As the javadoc says:

    This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.

    If you want to take the current real time and see what it is in Chicago and Tokyo, then you need to use either a universal time (Instant) or a time that know what time zone it represents (ZonedDateTime).

    Using Instant

    Instant now = Instant.now();
    ZonedDateTime chicago = now.atZone(ZoneId.of("America/New_York"));
    System.out.println("Chicago: " + chicago);
    System.out.println("Chicago formatted: " + chicago.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));
    
    ZonedDateTime tokyo = now.atZone(ZoneId.of("Asia/Tokyo"));
    System.out.println("Tokyo: " + tokyo);
    System.out.println("Tokyo formatted: " + tokyo.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));
    

    Output

    Chicago: 2017-11-05T20:02:45.444-05:00[America/New_York]
    Chicago formatted: 8:02:45 PM EST
    Tokyo: 2017-11-06T10:02:45.444+09:00[Asia/Tokyo]
    Tokyo formatted: 10:02:45 AM JST
    

    Using ZonedDateTime

    ZonedDateTime now = ZonedDateTime.now();
    ZonedDateTime chicago = now.withZoneSameInstant(ZoneId.of("America/New_York"));
    System.out.println("Chicago: " + chicago);
    System.out.println("Chicago formatted: " + chicago.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));
    
    ZonedDateTime tokyo = now.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
    System.out.println("Tokyo: " + tokyo);
    System.out.println("Tokyo formatted: " + tokyo.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));
    

    Output

    Chicago: 2017-11-05T20:04:19.368-05:00[America/New_York]
    Chicago formatted: 8:04:19 PM EST
    Tokyo: 2017-11-06T10:04:19.368+09:00[Asia/Tokyo]
    Tokyo formatted: 10:04:19 AM JST