Or “Why does @Jean have so much trouble with international announcements?”
How long is a day? Easy, 24 hours, give or take a few seconds, because planetary rotations and orbits aren’t static.
But how long is a date? Well, it can seem like forever if you aren’t interested in the other person…
Ooops, sorry, I meant, for a given date, say November 6, 2022, how many continuous hours is it that date somewhere on Earth? This is a different question than the number of hours in a day. I didn’t trust my mental arithmetic, so I wrote a little Haskell program to convince myself.
This is a literate Haskell program, and I’m going to use the standard time library, even though it lacks some elegance.
First, I’m going to calculate how many hours are in a day, just to verify that my method works. I’m going to take the difference of two date/time values and show the result in hours. The values represent midnight on successive dates, in the same timezone. I’m using UTC for convenience.
howLongIsADay :: Hours howLongIsADay = toHours (diffUTCTime ut1 ut0) ghci> howLongIsADay Hours 24
Great. So, if we stay within one timezone, we get the standard answer. But what if we consider the difference between the beginning of the day in New Zealand and the end of the day in Hawaii? For that, we need to start with ZonedTime values, convert them to UTC, and then take the difference.
howLongIsADate :: Hours howLongIsADate = toHours (diffZonedTime zt1 zt0) ghci> howLongIsADate Hours 46
Well, not 24, but also not 48. New Zealand is UTC+12 and Hawaii is UTC-10, which is a difference of 22 hours. Presumably I could find more exotic time zones 24 hours apart, but I don’t need to bother. The surprising part is that any particlar date spans 48 hours.
I suppose anyone who deals in international finance knows this quite well, but I don’t think I had understood this fully. The new reality has replaced my old, fuzzy understanding, but I think I would have thought about 36 hours, thinking sunrise to sunset…somehow.
If you find this confusing, just be glad I only used standard time. Many places change to and from daylight savings time on different dates, so the number of hours difference can change during the year.
Anyway, I expect that contributes to @Jean having a hard time scheduling these challenges. Pun intended.
newtype Hours = Hours Int deriving Show diffZonedTime :: ZonedTime -> ZonedTime -> NominalDiffTime diffZonedTime t1 t0 = diffUTCTime (zonedTimeToUTC t1) (zonedTimeToUTC t0) today :: Day today = ModifiedJulianDay 59889 tomorrow :: Day tomorrow = succ today -- I avoided using IO to simplify the presentation, but I acquired the correct -- number by running this once using it in the pure value of 'today', found above. today' :: IO Day today' = utctDay <$> getCurrentTime ut0 :: UTCTime ut0 = UTCTime today 0 ut1 :: UTCTime ut1 = UTCTime tomorrow 0 zt :: Day -> TimeZone -> ZonedTime zt d tz = ZonedTime (LocalTime d midnight) tz zt0 :: ZonedTime zt0 = zt today nzst zt1 :: ZonedTime zt1 = zt tomorrow hst nzst :: TimeZone nzst = TimeZone (12*60) False "NZST" hst :: TimeZone hst = TimeZone (-10*60) False "HST" toHours :: NominalDiffTime -> Hours toHours = Hours . cvt . truncate . nominalDiffTimeToSeconds where cvt h = h `div` (60*60)