jweir / elm-iso8601

Elm library to parse and convert ISO8601 times and dates
https://package.elm-lang.org/packages/jweir/elm-iso8601/latest
MIT License
15 stars 7 forks source link

Implement date formatting by composing formatting functions #3

Closed lohmander closed 8 years ago

lohmander commented 8 years ago

Implements date formatting by composing formatting functions as briefly discussed in #2.

Threw this together rather quickly. Will improve docs if we decide to go with this approach.

Anyways, the toString function works as usual, now you can however use the formatting functions to easily create your own formatter.

toYMD : Time -> String
toYMD =
    fmt (pad0 4 year >> sym "-" >> pad0 2 month >> sym "-" >> pad0 2 day)

toDayMonth : Time -> String
toDayMonth =
    fmt (day >> sym "/" >> month)

I think the pad0 function makes it a bit messy. Also still missing functions for 12-hour format, but it'd be trivial to add.

jweir commented 8 years ago

Thank you. I am merging to play with it. I can't quiet grok it from looking at the code. It might be a few days before I get back to you. In the meantime if you make any refinements – push em out.

jweir commented 8 years ago

Ok, I grok it now. The composition is interesting

t = fromTime 1469573340427
-- { year = 2016, month = 7, day = 26, hour = 22, minute = 49, second = 0, millisecond = 427, offset = (0,0) }
-- : ISO8601.Time
ymd s = pad0 4 year >> sym s >> pad0 2 month >> sym s >> pad0 2 day |> fmt
-- <function> : String -> ISO8601.Types.Time -> String
ymd "/" t
-- "2016/07/26" : String
ymd "-" t
-- "2016-07-26" : String

But is there a good reason to introduce the functions for year, second, etc when the fields can be accessed from the record? The below accomplishes the same thing with fewer functions:

pad size n = String.padLeft size '0' (Basics.toString n)

ymd' s t = pad 4 t.year ++ s ++ pad 2 t.month ++ s ++ pad 2 t.day
-- <function> : String -> { d | day : a, month : b, year : c } -> String
ymd' ":" t
--"2016:07:26" : String

That would keep the interface simpler. WDYT or am I missing something?

lohmander commented 8 years ago

So in your case, absolutely. The idea was that when we have a bit more complex formatting, like the hour in 12-hour format, timezone offset etc. it's be more convenient to just compose the different parts you want. And then have the exact same API for year, second etc.

toHHMM : Time -> String
toHHMM =
    fmt (zeroHour12 >> sym ":" >> zeroMinute >> amPm)

Or something like that.

But I see your point, also I'd think it'd be nice to get rid of the need to manually apply pad to the month, day and so on-functions and I think that'd make their purpose a bit more obvious.

At the end of the day, I think that it's just that I prefer the look and feel of this

toYMD : Time -> String
toYMD =
    fmt (year >> sym "-" >> zeroMonth >> sym "-" >> zeroDay)

to

toYMD : Time -> String
toYMD time =
    String.join ""
        [ time.year
        , "-"
        , pad 2 time.month
        , "-"
        , pad 2 time.day
        ]

-- or

toYMD : Time -> String
toYMD time =
    time.year ++ "-" pad 2 time.month ++ "-" pad 2 time.day

toHHMM : Time -> String
toHHMM time =
    pad 2 (fmt12Hour time.hour) ++ ":" ++ pad 2 time.minute ++ fmtAmPm time.hour

and the sometimes-add-a-formatter function approach. So in the "manual" case if you'd like to add the timezone offset you'd add something like fmtOffset time.offset at the end, but maybe not for year.

It's early in morning here so my thoughts aren't necessarily well organized just yet... ☕