Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect an ambiguous DST overlap in Joda Time?

In Joda Time, one can easily use the DateTimeZone.isLocalDateTimeGap method to tell if a local date and time is invalid because it falls into the gap created by a spring-forward daylight saving time transition.

DateTimeZone zone = DateTimeZone.forID("America/New_York");
LocalDateTime ldt = new LocalDateTime(2013, 3, 10, 2, 0);
boolean inGap = zone.isLocalDateTimeGap(ldt);  // true

But how do you detect the fall-back transition? In other words, if a local date and time could be ambiguous because there is an overlap, how do you detect that? I would expect something like zone.isLocalDateTimeOverlap, but it doesn't exist. If it did, I would use it like so:

DateTimeZone zone = DateTimeZone.forID("America/New_York");
LocalDateTime ldt = new LocalDateTime(2013, 11, 3, 1, 0);
boolean overlaps = zone.isLocalDateTimeOverlap(ldt);  // true

The Joda-Time documentation is clear that if there is an overlap during conversions, it will take the earlier possibility unless told otherwise. But it doesn't say how to detect that behavior.

like image 578
Matt Johnson-Pint Avatar asked Sep 13 '13 19:09

Matt Johnson-Pint


People also ask

How to handle DST in Java?

The right way to handle DST in Java is to instantiate a Timezone with a specific TZDB Timezone ID, eg. “Europe/Rome”. Then, we'll use this in conjunction with time-specific classes like java.util.Calendar to get a proper configuration of the TimeZone's raw offset (to the GMT time zone), and automatic DST shift adjustments.

How to create testable time-based code using Joda Time?

When there is no option to inject time provider or refactoring the whole class is no worth it, you may decide to use helper methods from Joda Time to achieve testable time-based code: With Joda Time we can use static method setCurrentTimeMillisFixed (), which will tell Joda objects to always return given value. According to documentation:

How does Joda-Time define daylight saving time?

Note: Some governments, most notably Ireland, define daylight saving by describing a "standard" time in summer and a negative DST offset in winter. Joda-Time, like the JDK, follows a model for time-zone data where there is a raw offset all year round and a positive additional offset.

How to use Joda Time Java library in Maven?

To use Joda Time Java library in the Gradle build project, add the following dependency into the build.gradle file. To use Joda Time Java library in the Maven build project, add the following dependency into the pom.xml file. To download the Joda Time .jar file you can visit Joda Time releases page at github.com/JodaOrg/joda-time


1 Answers

Take advantage of withEarlierOffsetAtOverlap()

public static boolean isInOverlap(LocalDateTime ldt, DateTimeZone dtz) {
    DateTime dt1 = ldt.toDateTime(dtz).withEarlierOffsetAtOverlap();
    DateTime dt2 = dt1.withLaterOffsetAtOverlap();
    return dt1.getMillis() != dt2.getMillis();
}


public static void test() {
    // CET DST rolls back at 2011-10-30 2:59:59 (+02) to 2011-10-30 2:00:00 (+01)
    final DateTimeZone dtz = DateTimeZone.forID("CET");
    LocalDateTime ldt1 = new LocalDateTime(2011,10,30,1,50,0,0); // not in overlap
    LocalDateTime ldt2 = new LocalDateTime(2011,10,30,2,50,0,0); // in overlap
    System.out.println(ldt1 + " is in overlap? " + isInOverlap(ldt1, dtz)); 
    System.out.println(ldt2 + " is in overlap? " + isInOverlap(ldt2, dtz)); 
}
like image 157
leonbloy Avatar answered Oct 17 '22 00:10

leonbloy