Как получить текущее время в Elm?

Я запускаю elm-repl, чтобы поиграть с языком.

Я хотел бы посмотреть, какое сейчас время. Как мне это сделать? Кажется, что это невозможно в текущей библиотеке. Почему это?


EDIT: Я сделал пакет, чтобы помочь с этим. http://package.elm-lang.org/packages/z5h/time-app

Об этом спросили около вяза 0.15 - все в другом 0.17 и 0.18: см. Как получить текущее время в Elm 0.17/0.18?

Ответы

Ответ 1

Чтобы решить мой собственный вопрос, я создал вариант StartApp, который включает метку времени для каждого действия.
Таким образом, функция обновления имеет подпись:
update : action -> Time -> model -> (model, Effects action)

Суть здесь. https://gist.github.com/z5h/41ca436679591b6c3e51

Ответ 2

Обновление для 0.19 Невозможно получить текущее время, используя стандартную библиотеку. Вам нужно использовать elm/time. Как и в 0.18, все, что вам нужно, это команда и сообщение, чтобы обработать результат

type Msg
    = OnTime Time.Posix 

getTime : Cmd Msg
getTime = 
    Task.perform OnTime Time.now 

Обновление для 0.18 Это снова стало проще. Теперь все, что вам нужно, это команда и сообщение для обработки результата

type Msg
    = OnTime Time 

getTime : Cmd Msg
getTime = 
    Task.perform OnTime Time.now 

Посмотри на Элли

Оригинальный ответ

С 0.17 это стало намного проще. Теперь есть задача в библиотеке времени. Так, например, теперь у нас есть:

Time.now
|> Task.Perform NoOp CurrentTime

Ответ 3

Вы можете использовать пакет времени и/или пакет даты.

Здесь надуманный пример, который использует оба:

import Signal
import Time exposing (every, second)
import Date exposing (year, hour, minute, second, fromTime)
import Graphics.Element exposing (show)

main =
  Signal.map currentTime (Time.every Time.second)

currentTime t =
  let date' = fromTime t
      hour' = toString (Date.hour date')
      minute' = toString (Date.minute date')
      second' = toString (Date.second date')
      year' = toString (year date')
      now = "The current time is: " ++ hour' ++ ":" ++ minute' ++ ":" ++ second'
  in 
      show now

Ответ 4

Если вы хотите установить время с момента запуска программы, вы можете сделать следующее:

Now.elm

module Now where

import Native.Now

loadTime : Float
loadTime = Native.Now.loadTime

Native/Now.js

Elm.Native.Now = {};

Elm.Native.Now.make = function(localRuntime) {

  localRuntime.Native = localRuntime.Native || {};


  localRuntime.Native.Now = localRuntime.Native.Now || {};

  if (localRuntime.Native.Now.values) {
    return localRuntime.Native.Now.values;
  }

  var Result = Elm.Result.make(localRuntime);

  return localRuntime.Native.Now.values = {
    loadTime: (new window.Date).getTime()
  };

};

ваш код

programStart = Now.loadTime

Ответ 5

Вяз 0,19

Ниже я установил начальное время как время начала unix Time.millisToPosix 0, но вы можете установить его Time.millisToPosix 0 Nothing а позже - Just time или передать его с Flag.

module Main exposing (main)

import Browser
import Html exposing (Html)
import Task
import Time exposing (Posix)


main : Program () Model Msg
main =
    Browser.element
        { init = \_ -> init
        , view = view
        , update = update
        , subscriptions = \_ -> Sub.none
        }



-- MODEL


type alias Model =
    { zone : Time.Zone
    , now : Posix
    }


init : ( Model, Cmd Msg )
init =
    ( Model Time.utc (Time.millisToPosix 0), Task.perform Zone Time.here )



-- UPDATE


type Msg
    = Zone Time.Zone
    | Now Posix


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Zone zone ->
            ( { model | zone = zone }, Task.perform Now Time.now )

        Now now ->
            ( { model | now = now }, Cmd.none )



-- VIEW


formatTime zone posix =
    (String.padLeft 2 '0' <| String.fromInt <| Time.toHour zone posix)
        ++ ":"
        ++ (String.padLeft 2 '0' <| String.fromInt <| Time.toMinute zone posix)
        ++ ":"
        ++ (String.padLeft 2 '0' <| String.fromInt <| Time.toSecond zone posix)


view : Model -> Html Msg
view model =
    Html.div []
        [ Html.text <| formatTime model.zone model.now
        ]

Ответ 6

Вы можете увидеть pdoherty926 answer за то, как сделать что-то с текущим временем в Elm.

elm-repl не имеет возможности работать с Signal s, а время "изменяется со временем", поэтому это сигнал. Там также нет Task для получения времени, о котором я знаю. Не способ выполнения задач в repl, хотя я ожидаю, что это будет функция в будущем.

Ответ 7

Есть два основных способа, с которыми я могу думать, чтобы работать с текущим временем в Elm:

  • Записать/использовать собственный модуль для создания функции, которая возвращает текущее время в ms (или возвращает задачу, которая будет делать то же самое). Этот метод обычно не рекомендуется. Я считаю, что № 2 - лучший подход. Но пример № 1 можно найти здесь: https://github.com/evancz/task-tutorial/blob/1.0.2/src/TaskTutorial.elm (см. Функцию getCurrentTime)

  • Напишите программу, используя архитектуру приложения Elm (https://github.com/evancz/elm-architecture-tutorial/), а затем подайте текущий сигнал времени в качестве входа в цикл обновления, обновление модели с новым текущим временем в каждый выбранный вами интервал. Затем все ваши другие методы могут просто синхронизировать текущее время с моделью.

Ответ 8

Ответ (для 0.18) от Саймона Х заставил меня начать в правильном направлении, но у меня были некоторые затруднения, решающие, как фактически сделать что-то с этим временем. (user2167582 добавляет комментарий к ответу Саймона, который спрашивает то же самое: как вы "получаете время?").

Моя конкретная проблема заключалась в том, что я хотел включить текущее время в теле сообщения POST на сервер.

В конце концов я решил это и был весьма доволен конечным результатом - использование Task.andThen означало, что я в своей функции postTime могу просто использовать timestamp в качестве "обычного" параметра с плавающей запятой (что и происходит при запуске задачи)., Я полагаю).

Мой полный ТАК ответ здесь.

Ниже приведено решение, которое я придумала, и вот оно в Элли:

module Main exposing (..)

import Html exposing (..)
import Html.Events exposing (..)
import Http
import Json.Decode as JD
import Json.Encode as JE
import Task
import Time


type alias Model =
    { url : String
    }


type Msg
    = PostTimeToServer
    | PostDone (Result Http.Error String)


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        PostTimeToServer ->
            ( model, postTimeToServer model.url )

        PostDone _ ->
            ( model, Cmd.none )


view : Model -> Html Msg
view model =
    div []
        [ div []
            [ button [ onClick PostTimeToServer ] [ Html.text "POST the current time." ]
            ]
        ]


postTimeToServer : String -> Cmd Msg
postTimeToServer url =
    let
        getTime =
            Time.now

        postTime t =
            JD.string
                |> Http.post url (JE.float t |> Http.jsonBody)
                |> Http.toTask

        request =
            getTime                                            <<-- Here is
                |> Task.andThen postTime                       <<-- the key bit.
    in
        Task.attempt PostDone request


main =
    Html.program
        { init = ( Model "url_here", Cmd.none )
        , update = update
        , view = view
        , subscriptions = always Sub.none
        }