latis-data / latis3

Apache License 2.0
8 stars 1 forks source link

Time conversion with leap seconds #686

Closed dlindhol closed 4 months ago

dlindhol commented 4 months ago

I've decided that we really don't need to capture the distinction between the "naive" Java/Unix/POSIX time scale and UTC like we do in latis2. They both count the same other than UTC going off in some dimension to count a leap second (waiting for Earth to catch up) while the former just ignores the leap second and allows NTP to keep it synced. Actually, part of my confusion has been due to the fact that UTC isn't really a "scale" in that there is not a continuous accumulation of fixed size steps. I'm coming to think of UTC as the formatted time string that points to a point on the time line instead of a count (which is why we can use it as an epoch). So, we'll use Java time to manage the counting and format mapping (and throw an error if anyone tries to give us 23:59:60 as implemented by Java's DateTimeFormatter without the LENIENT setting).

Since we are heavily dependent on the Java time implementation, I am content to lean on the replay of the leap second, rather than smear the leap second (change the length of a second) or make a day 86401 seconds long. I confirmed that with a LENIENT DateTimeFormatter, you can represent a leap second with 23:59:60 but I think it simply rolls over to the 00:00:00 of the next day. Then when 00:00:00 plays out, it will return to the first second of the day that it just played.

My other concern had been about durations. The implementations that I've looked at, including Java's, do not include leap seconds when computing a duration. So, I'm content to say that our default time scale type is UTC which remains aligned with Unix time and ignores leap seconds (least surprising). If users want accurate durations, they should be using a TAI time scale.

The logic for the time conversions is hard to reason about, so I would lean on the tests. (I felt like there were so many more that I could write.) Keep in mind that I am creating a sorted map as a lookup table. It is optimized by having already converted the keys/values to the units of the inputs/outputs.