Time Formatting Parsing in Elm

Time formatting and parsing in Elm is handled differently than in other languages. Elm uses the Time module for working with time, and the DateFormat module for formatting dates and times.

First, let’s import the necessary modules:

import Time
import DateFormat

Now, let’s look at how to get the current time and format it:

currentTime : Task x Time.Posix
currentTime =
    Time.now

formattedTime : Time.Zone -> Time.Posix -> String
formattedTime zone time =
    DateFormat.format
        [ DateFormat.yearNumber
        , DateFormat.text "-"
        , DateFormat.monthNumber
        , DateFormat.text "-"
        , DateFormat.dayOfMonthNumber
        , DateFormat.text "T"
        , DateFormat.hourMilitaryNumber
        , DateFormat.text ":"
        , DateFormat.minuteNumber
        , DateFormat.text ":"
        , DateFormat.secondNumber
        , DateFormat.text "Z"
        ]
        zone
        time

To parse a time string, we can use the Iso8601 module:

import Iso8601

parsedTime : Result String Time.Posix
parsedTime =
    Iso8601.toTime "2012-11-01T22:08:41+00:00"

Custom formatting in Elm is done by composing format specifiers:

customFormat : Time.Zone -> Time.Posix -> String
customFormat zone time =
    DateFormat.format
        [ DateFormat.hourNumber
        , DateFormat.text ":"
        , DateFormat.minuteNumber
        , DateFormat.amPmUppercase
        ]
        zone
        time

For purely numeric representations, you can use the individual components of the time:

numericFormat : Time.Zone -> Time.Posix -> String
numericFormat zone time =
    String.join "-"
        [ String.fromInt (Time.toYear zone time)
        , String.padLeft 2 '0' (String.fromInt (Time.toMonth zone time |> monthToInt))
        , String.padLeft 2 '0' (String.fromInt (Time.toDay zone time))
        ]

monthToInt : Time.Month -> Int
monthToInt month =
    case month of
        Time.Jan -> 1
        Time.Feb -> 2
        -- ... other months ...
        Time.Dec -> 12

In Elm, parsing errors are typically handled through the Result type:

parseResult : Result String Time.Posix
parseResult =
    Iso8601.toTime "invalid time string"

case parseResult of
    Ok time ->
        "Successfully parsed time"

    Err error ->
        "Error parsing time: " ++ error

Note that Elm’s approach to time formatting and parsing is quite different from other languages. It emphasizes type safety and correctness, which can make some operations more verbose but also helps prevent runtime errors.