Current year with 4 digits in elm 0.19.1

折月煮酒 提交于 2020-08-25 07:05:51

问题


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?


回答1:


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) ]



回答2:


As I already said in my comment, it's impossible to define a function in Elm that returns the current year. You have to get such information from the Elm runtime system (which is basically JavaScript, but you don't have to write it yourself). This happens via commands, where you tell the runtime system to do something for you. But note that you can't simply retrieve the "return value" of that command and get it back into your Elm code. Instead you have to pass it into a function that can convert it into a "message" (see basic Elm Architecture tutorial here, it's fundamental to understand this before you can do anything with Elm) - this then allows you to store the value in your Model and thereby display it in your app.

These patterns do take some getting your head around, especially if you're not used to pure functional programming - but once you get used to it the benefits are huge, including a near guaranteed absence of runtime errors, and greatly enhanced ability to reason about your code.

For getting the year specifically, it looks like you need this library, which gives you (as now) a Task rather than a Cmd. You can use Task.perform to convert it to a command, which is documented here - in fact it even gives an example that matches your use case quite closely - I'll copy it here for posterity:

import Time  -- elm install elm/time
import Task

type Msg
  = Click
  | Search String
  | NewTime Time.Posix

getNewTime : Cmd Msg
getNewTime =
  Task.perform NewTime Time.now

You'll have to fill this in to fit your own use case, in particular your own Msg type. But it gives a good basic outline. To get the user's current year, you need to replace the Time.Posix type with Int, and the Time.now command with (Task.map2 Time.toYear Time.here Time.now), as explained by @bdukes in his answer.



来源:https://stackoverflow.com/questions/61259718/current-year-with-4-digits-in-elm-0-19-1

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!