Home > Enterprise >  How to specify time after daylight saveing time shift in Java
How to specify time after daylight saveing time shift in Java

Time:03-12

Using the following code:

class Test {
    public static void main(String [] args) {
        LocalDate date = LocalDate.of(2018, 11, 4);
        LocalTime time = LocalTime.of(1, 59);
        ZonedDateTime dt = ZonedDateTime.of(date, time, ZoneId.of("America/New_York"));
        System.out.println(dt.getHour()   ":"   dt.getMinute()   ":"   dt.getSecond());
        dt = dt.plusMinutes(1);
        System.out.println(dt.getHour()   ":"   dt.getMinute()   ":"   dt.getSecond());
        dt = dt.plusMinutes(59);
        System.out.println(dt.getHour()   ":"   dt.getMinute()   ":"   dt.getSecond());
        dt = dt.plusMinutes(1);
        System.out.println(dt.getHour()   ":"   dt.getMinute()   ":"   dt.getSecond());
    }
}

I get

1:59:0
1:0:0
1:59:0
2:0:0

Is there a way to get to the 1:00:00 from after daylight saving time without going through the 1:00:00 from before daylight saving time?

CodePudding user response:

Use ofStrict to specify which offset you want the resulting zoned date time to be on. America/New_York changes from -04:00 to -05:00 at around the time in question, so you want ZoneOffset.ofHours(-5).

ZonedDateTime dt = ZonedDateTime.ofStrict(
    LocalDateTime.of(date, time), 
    ZoneOffset.ofHours(-5), 
    ZoneId.of("America/New_York")
);

In case you cannot hardcode the offset in, you can get the offset after using:

var dateTime = LocalDateTime.of(date, time)
var zone = ZoneId.of("America/New_York");
var offsetAfter = zone.getRules()
    .getTransition(dateTime)
    .getOffsetAfter();
ZonedDateTime dt = ZonedDateTime.ofStrict(
    dateTime, 
    offsetAfter, 
    zone
);

CodePudding user response:

The problem with time zones that honor Daylight Saving Time is that such times are ambiguous. The "America/New_York" zone has two times that are both labeled 2008-11-04T01:00:00. Technically, one of them is 01:00 EDT and the other is 01:00 EST, but not a lot of software will let you make the distinction that way, not least since such three-letter time zone designations are not necessarily globally unique.

The solution is to specify the time either in or relative to Universal time, which doesn't have daylight saving: the first 01:00 Eastern time is 05:00Z, and the second is 06:00Z. So you can either give the time as one of those and the zone as "UTC" (and then convert the result to "America/New_York"), or specify the offset from UTC using ofStrict.

  • Related