I'm trying to convert ZonedDateTime (EST) to Date (UTC) i see 1 hour off for the month of march for 13 and 14th calendar date
SystemDefault - UTC
ZonedDateTime zonedDateTime1 = ZonedDateTime.of(2021, 3, 13, 19, 0, 0, 0, ZoneId.of("America/New_York"));
Date date1 = Date.from(zonedDateTime1.withZoneSameInstant(ZoneId.systemDefault()).toInstant();
System.out.println("EST -> ", zonedDateTime1);
System.out.println("UTC -> ", date1);
ZonedDateTime zonedDateTime2 = ZonedDateTime.of(2021, 3, 14, 19, 0, 0, 0, ZoneId.of("America/New_York"));
Date date2 = Date.from(zonedDateTime2.withZoneSameInstant(ZoneId.systemDefault()).toInstant();
System.out.println("EST -> ", zonedDateTime2);
System.out.println("UTC -> ", date2);
Actual Result :
EST -> 2021-03-13T19:00-05:00[America/New_York]
UTC -> Sun Mar 14 00:00:00 UTC 2021
EST -> 2021-03-14T19:00-04:00[America/New_York]
UTC -> Sun Mar 14 23:00:00 UTC 2021Expected Result :
EST -> 2021-03-13T19:00-05:00[America/New_York]
UTC -> Sun Mar 14 00:00:00 UTC 2021
EST -> 2021-03-14T 19:00-04:00 [America/New_York]
UTC -> Mon Mar 15 00:00:00 UTC 2021
Here is business use case
-> Client specific holidays 2021/1/14, 2021/2/14, 2021/3/14 (These are in UTC)
-> user selects a specific time eg: 2021/2/14 19:00, 2021/3/14 19:00 EST (These two days are actual working days)
Now system has say user selected date is a holiday or working day for client
For this I converted user selected date (EST) to UTC and checking against client specific calendar (it works for feb but fails for march)
On Sun March 14th daylight saving time started in America/New_York
. I suppose this is the reason for the observed difference.
Daylight saving time for America/New_York
started on 2021-03-14T02:00:00 EST
. That is any date time instance after this (until winter time is effective again) for time zone America/New_York
will be EDT and not EST. And EDT has a UTC offset of -4 hours.
It seems that your client insists on reporting times in EST, Eastern Standard Time, all year, not EDT, Eastern Daylight Time, in summer. There are time zones that do that, so a solution is: instead of using America/New_York time zone, use a time zone that uses Eastern Time and doesn't use summer time/DST. For example:
ZoneId clientTimeZone = ZoneId.of("America/Atikokan");
ZonedDateTime zonedDateTime1 = ZonedDateTime.of(2021, 3, 13, 19, 0, 0, 0, clientTimeZone);
Date date1 = Date.from(zonedDateTime1.toInstant());
System.out.println("EST -> " + zonedDateTime1);
System.out.println("UTC -> " + date1);
ZonedDateTime zonedDateTime2 = ZonedDateTime.of(2021, 3, 14, 19, 0, 0, 0, clientTimeZone);
Date date2 = Date.from(zonedDateTime2.toInstant());
System.out.println("EST -> " + zonedDateTime2);
System.out.println("UTC -> " + date2);
Output is (when running in UTC time zone):
EST -> 2021-03-13T19:00-05:00[America/Atikokan] UTC -> Sun Mar 14 00:00:00 UTC 2021 EST -> 2021-03-14T19:00-05:00[America/Atikokan] UTC -> Mon Mar 15 00:00:00 UTC 2021
Compared to what you expected, the differences are:
2021-03-14T19:00
is now not -04:00
but -05:00
. Which is what causes the time to be converted to the expected UTC time of 00:00. Compared to your code I have made one other change: I have left the calls to withZoneSameInstant()
out. They make no difference here. Since you are doing toInstant()
afterward, as the method names say, you get the same instant in both cases.
Edit: North and Central American time zones using Eastern Standard Time all year include:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.