Time in Elm

import Time
import Task exposing (Task)

-- We'll start by getting the current time.
getCurrentTime : Task Never Time.Posix
getCurrentTime =
    Time.now

-- You can build a Time.Posix value by providing the
-- milliseconds since the Unix epoch.
customTime : Time.Posix
customTime =
    Time.millisToPosix 1258490098651

-- You can extract the various components of the time
-- value as expected.
extractComponents : Time.Posix -> Time.Zone -> List Int
extractComponents time zone =
    [ Time.toYear zone time
    , Time.toMonth zone time |> monthToNumber
    , Time.toDay zone time
    , Time.toHour zone time
    , Time.toMinute zone time
    , Time.toSecond zone time
    , Time.toMillis zone time
    ]

-- The day of the week is also available.
getWeekday : Time.Posix -> Time.Zone -> Time.Weekday
getWeekday time zone =
    Time.toWeekday zone time

-- These functions compare two times, testing if the
-- first occurs before, after, or at the same time
-- as the second, respectively.
compareTime : Time.Posix -> Time.Posix -> (Bool, Bool, Bool)
compareTime t1 t2 =
    ( Time.posixToMillis t1 < Time.posixToMillis t2
    , Time.posixToMillis t1 > Time.posixToMillis t2
    , Time.posixToMillis t1 == Time.posixToMillis t2
    )

-- We can compute the difference between two times.
timeDifference : Time.Posix -> Time.Posix -> Int
timeDifference t1 t2 =
    Time.posixToMillis t2 - Time.posixToMillis t1

-- We can advance a time by a given duration.
advanceTime : Time.Posix -> Int -> Time.Posix
advanceTime time duration =
    Time.millisToPosix (Time.posixToMillis time + duration)

-- Helper function to convert Time.Month to Int
monthToNumber : Time.Month -> Int
monthToNumber month =
    case month of
        Time.Jan -> 1
        Time.Feb -> 2
        Time.Mar -> 3
        Time.Apr -> 4
        Time.May -> 5
        Time.Jun -> 6
        Time.Jul -> 7
        Time.Aug -> 8
        Time.Sep -> 9
        Time.Oct -> 10
        Time.Nov -> 11
        Time.Dec -> 12

main : Program () () Msg
main =
    Platform.worker
        { init = \_ -> ((), Cmd.none)
        , update = \_ model -> (model, Cmd.none)
        , subscriptions = \_ -> Sub.none
        }

This Elm code demonstrates various operations with time, similar to the original example. Here’s a breakdown of the main differences and adaptations:

  1. Elm uses Time.Posix to represent time, which is similar to the time.Time in the original example.

  2. Instead of creating a time with specific components, we use Time.millisToPosix to create a custom time from milliseconds since the Unix epoch.

  3. Elm separates the time value (Time.Posix) from the time zone (Time.Zone). Most functions that extract components from a time require both the time and the zone.

  4. The extractComponents function demonstrates how to get various components of a time value in Elm.

  5. Elm doesn’t have built-in functions for comparing times directly. We create a compareTime function that compares the underlying millisecond values.

  6. Instead of a Duration type, we work with milliseconds as integers for time differences and advancements.

  7. Elm doesn’t have a direct equivalent to Go’s Add method for times. We create an advanceTime function that adds a duration in milliseconds to a time.

  8. The main function is included to make this a valid Elm program, but it doesn’t perform any operations. In a real application, you would use these functions within your update and view logic.

Note that Elm is a functional language and doesn’t have side effects in the same way as Go. Operations that would print to the console in the Go example would typically be part of the Model in Elm and would be rendered in the View.