It’s pretty typical that an app uses several different units or “granularities” of time. You might have timestamps that are in Posix/milliseconds or seconds, datepickers which have days as their smallest unit, and if you’re doing schedules you might also be using hours and/or minutes.
You could use Time.Posix for everything, treating dates as “the first millisecond of the day” etc. but that can lead to confusion and bugs where a value that’s supposed to represent a date like “2019-06-27” gets displayed as “2019-06-26” because of timezones or daylight savings.
We’re currently using justinmimbs/date for our dates, which avoids that problem, although we’re also using year/month pickers, and it doesn’t feel quite right to store their values as “the first day of the month”. We could of course create a custom “Period” type for this, but then we would dealing with three different time types with different interfaces.
I was thinking if there was a way to create a system that could handle all these units of time in a unified way, and thought maybe extensible records could be a solution?
Each unit of time would have a type alias like:
type alias Period r =
    { r
        | year : Int
        , month : Int
    }
type alias Date r =
    { r
        | year : Int
        , month : Int
        , day : Int
    }
type alias Millis r =
    { r
        | year : Int
        , month : Int
        , day : Int
        , hour : Int
        , minute : Int
        , second : Int
        , millis : Int
    }
This then lets you write functions like:
diffDays : Date a -> Date b -> Int
diffDays a b =
    diffMonths a b * 30 + (b.day - a.day)
diffDays can then be used to for example compare a Date with a Millis. But if you tried to use it with a Period the type system will prevent it, since Period doesn’t include days.
Here’s the full code: https://github.com/Herteby/elm-chrono/blob/master/src/Chrono.elm
(It’s just a mockup so far, it currently assumes all months are 30 days for example :P)
But what do you think, would this be worthwhile, or should we just stick to Time and Date? Is this whole thing just bit of OCD and not really worth worrying about?

