Local time validation with daylight

448 views Asked by At

We have a requirement in java to validate the local time before it is passed to scheduler like quartz. System receives London local time say 01:30 AM but this time in not valid on March 26 2017 (daylight savings). How do I write a code to output below results?

Input

12:30, 01:30, 02:30

Output

Mar 26 2017 12:30   ->  Valid, GMT   
Mar 26 2017 01:30   ->  Invalid, NA   
Mar 26 2017 02:30   ->  Valid, BST
2

There are 2 answers

2
massfords On

Assuming that you start with a LocalDateTime then you can test to see if it's valid for scheduling by seeing if a given timezone reports that there are valid offsets for the time. This info is available in the ZoneRules class.

Here's some sample code:

@Test
public void test() throws Exception {

    TimeZone tz = TimeZone.getTimeZone("Europe/London");
    ZoneId londonZone = tz.toZoneId();

    String springAhead = "2017-03-26T01:30";

    assertFalse(isValidForScheduling(londonZone, LocalDateTime.parse(springAhead)));

    String fallBack = "2017-10-29T01:30";

    assertFalse(isValidForScheduling(londonZone, LocalDateTime.parse(fallBack)));
}

private boolean isValidForScheduling(ZoneId zoneId, LocalDateTime ldt) {
    ZoneRules rules = zoneId.getRules();

    List<ZoneOffset> validOffsets = rules.getValidOffsets(ldt);
    return validOffsets.size() == 1;
}

If the list of validOffsets is empty then it's not a valid time. If there is more than 1 entry then the time occurs multiple times in that zone (the case of putting the clocks back). If there's a single entry, then it's a regular time.

You'd probably want to fail on an empty list and warn on a list with multiple entries.

0
J J On

The below code errors only for March 26 2017 1AM-2AM. I didnt like the way it is written. Can it be refactored? This doesn't error on Oct 29 2017.
LocalDateTime localDateTime = LocalDateTime.of(2017, 3, 26, hours, minutes);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.of("Europe/London"));
if ( zonedDateTime.getHour() != localDateTime.getHour() ) {
System.out.println("MISMATCH!!!");
}