Home > Software design >  Daylight Savings Time DST Finding Difference between two dates
Daylight Savings Time DST Finding Difference between two dates

Time:03-05

We are sent two dates from an external source as Strings. We then calculate the difference between the dates to see how many hours they worked.

Two times a year due to the time change - Our calculations get wrong. We use Java. How do you solve a problem like this?

CodePudding user response:

It really depends on what your input data is and precisely what you're trying to determine.

If you're just receiving the dates, represent them as LocalDate values - that's what LocalDate represents; a date without any associated time zone. You can then use Period.between to find out the difference between LocalDate values, for example.

However, if you want to actually work out an elapsed time between two instants in time, then you do need to take time zones into account - in which case you might parse into an OffsetDateTime or a ZonedDateTime (or perhaps directly Instant - it depends on your input data). You can find the elapsed Duration between any two Temporal values (such as OffsetDateTime and ZonedDateTime, or Instant) using Duration.between.

It's worth noting that if your input data specifies a time zone (e.g. Europe/London) and a local date/time, you will need to consider ambiguous local date/time values. For example, suppose the file is something like:

Time zone: Europe/London
Shift 1 start: 2022-10-31T01:30
Shift 1 end: 2022-10-31T02:30

Should that be one hour, or two? It could be either, because 1:30am happened twice in the Europe/London time zone on that day, as the clocks went back from 2am to 1am. You could even end up with data that seems implausible at first glance:

Time zone: Europe/London
Shift 1 start: 2022-10-31T01:30
Shift 1 end: 2022-10-31T01:15

That's entirely valid as a 45 minute shift, if it started at the first occurrence of 1:30, and ended at the second occurrence of 1:15.

CodePudding user response:

A good way to represent correct points in time that, once constructed, allow calculations independent of any assumed time zone is ZonedDateTime. Whats nice about this class is that you can create instances of it easily using your own idea of local time. You just need to tell it what time zone you're in, and it will do the right thing for daylight savings time as defined for your time zone. Once constructed, you can do date/time arithmetic on these objects without concern for time zone or DST state.

Here are the two simple cases for creating and subtracting two ZonedDateTime objects representing an 8 hour timespan, one that spans a DST change, and one that doesn't. There is likely a way to do this with Java's date functions such that you never have to see and deal with the individual numbers.

Case 1: Worker works 8 hours that don't cross a DST point:

ZonedDateTime zdt = ZonedDateTime.of(
        2022, 1, 13, 1, 0, 0, 0, ZoneId.of("America/Los_Angeles"));
ZonedDateTime zdt2 = ZonedDateTime.of(
        2022, 1, 13, 9, 0, 0, 0, ZoneId.of("America/Los_Angeles"));
long hours = ChronoUnit.HOURS.between(zdt, zdt2);
System.out.println(hours);

Result:

8

Case 2: Worker works 8 hours that cross a DST point:

ZonedDateTime zdt = ZonedDateTime.of(
        2022, 3, 13, 1, 0, 0, 0, ZoneId.of("America/Los_Angeles"));
ZonedDateTime zdt2 = ZonedDateTime.of(
        2022, 3, 13, 10, 0, 0, 0, ZoneId.of("America/Los_Angeles"));
long hours = ChronoUnit.HOURS.between(zdt, zdt2);
System.out.println(hours);

Result:

8

Notice that if you forgot about DST, you'd think that for the second shift, the worker worked an extra hour. But given DST, the two shifts were the same number of hours.

NOTE: I started from numeric representations of date/times because the question does not give examples of or otherwise specify the formats of the input strings involved. A "correct" example that involved string parsing would need to assume a format that might be different than what the OP is starting with. The primary question here would be if and how time zone is represented in those strings. Parsing a string to come up with a set of numbers and a time zone is a separate problem that has nothing to do with DST, so I leave that for the OP to figure out. It is likely that you could use date/time parsing logic in the Java date/time library to directly arrive at a ZonedDateTime, again, dependent on the format of the strings.

  • Related