问题
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