Search code examples
dateelm

Current year with 4 digits in elm 0.19.1


How can I do a function to get the current year with 4 digits using ELM 0.19.1? I have read something but nothing works with 0.19.1.

Signature:

getCurrentYear : Int

Execution:

getCurrentYear => 2020

Edit:

Maybe executing new Date().getFullYear() javascript code?


Solution

  • The simplest way would be to pass the year in via flags when you start the app, since the current year isn't likely to change in the course of the application running. In that case, you can use the snippet of JavaScript you suggested (ellie example):

        Elm.Main.init({ 
          node: document.querySelector('main'), 
          flags: {
            year: new Date().getFullYear(),
          } 
        });
    
    module Main exposing (main)
    
    import Browser
    import Html exposing (Html, p, text)
    
    
    type alias Flags =
        { year : Int }
    
    
    main : Program Flags Model Msg
    main =
        Browser.element
            { init = \flags -> ( Model flags.year, Cmd.none )
            , view = view
            , update = update
            , subscriptions = \_ -> Sub.none
            }
    
    
    type alias Model =
        { year : Int }
    
    
    type Msg
        = NoOp
    
    
    update : Msg -> Model -> ( Model, Cmd Msg )
    update msg model =
        case msg of
            NoOp ->
                ( model, Cmd.none )
    
    
    view : Model -> Html Msg
    view model =
        p [] [ text "The year is ", text (String.fromInt model.year) ]
    

    Alternatively, you can use Time.now to request the current time, as Robin Zigmond's answer suggests, however that is pointing to Elm 0.18 documentation (for elm-lang/core instead of elm/time). For 0.19, you need both a Time.Posix and a Time.Zone in order to call Time.toYear. You can chain Time.now (a Task producing a Posix value) and Time.here (a Task producing a Zone with the current time zone offset) to retrieve those values in one Cmd. Here's an example (also on ellie)

    module Main exposing (main)
    
    import Browser
    import Html exposing (Html, p, text)
    import Task exposing (Task)
    import Time
    
    
    type alias Flags =
        { year : Int }
    
    
    main : Program () Model Msg
    main =
        Browser.element
            { init = \() -> ( Model 0, whatYearIsIt |> Task.perform GotYear )
            , view = view
            , update = update
            , subscriptions = \_ -> Sub.none
            }
    
    
    whatYearIsIt : Task x Int
    whatYearIsIt =
        Task.map2 Time.toYear Time.here Time.now
    
    
    type alias Model =
        { year : Int }
    
    
    type Msg
        = GotYear Int
    
    
    update : Msg -> Model -> ( Model, Cmd Msg )
    update msg model =
        case msg of
            GotYear year ->
                ( { model | year = year }, Cmd.none )
    
    
    view : Model -> Html Msg
    view model =
        p [] [ text "The year is ", text (String.fromInt model.year) ]