榆树:Json解码器时间戳到日期

Gui*_*las 12 elm

我正在尝试将时间戳(例如:"1493287973015")从JSON转换为Date类型.

到目前为止,我创建了这个定制解码

stringToDate : Decoder String -> Decoder Date
stringToDate decoder =
  customDecoder decoder Date.fromTime
Run Code Online (Sandbox Code Playgroud)

但它不起作用,因为它返回结果,而不是日期:

Function `customDecoder` is expecting the 2nd argument to be:

    Time.Time -> Result String a

But it is:

    Time.Time -> Date.Date
Run Code Online (Sandbox Code Playgroud)

有没有办法进行转换?

Cha*_*ert 17

假设您的JSON实际上将数值放在引号内(意味着您正在解析JSON值"1493287973015"而不是1493287973015),您的解码器可能如下所示:

import Json.Decode exposing (..)
import Date
import String

stringToDate : Decoder Date.Date
stringToDate =
  string
    |> andThen (\val ->
        case String.toFloat val of
          Err err -> fail err
          Ok ms -> succeed <| Date.fromTime ms)
Run Code Online (Sandbox Code Playgroud)

请注意,stringToDate没有传递任何参数,与您尝试将a Decoder String作为参数传递的示例相反.这不是解码器的工作方式.

相反,这可以通过构建更原始的解码器来完成,在这种情况下,我们从解码器string开始Json.Decode.

andThen然后该部分获取解码器给出的字符串值,并尝试将其解析为浮点数.如果它是有效的Float,它被输入Date.fromTime,否则,它是失败的.

failsucceed功能包你处理的正常值为Decoder Date.Date背景,使他们能够返回.

  • 我不会说它不是_easy_.如果你来自一个势在必行的背景,那就太陌生了.这种解析在函数式语言中相当普遍; 它被称为Parser Combinators. (3认同)

小智 6

两件事,JSON 实际上可能将毫秒作为整数,而不是字符串,并且自 Elm 的 v 0.19 以来发生了变化。

鉴于您的 JSON 看起来像。

{
    ...
    "someTime": 1552483995395,
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后这将解码为 Time.Posix:

import Json.Decode as Decode

decodeTime : Decode.Decoder Time.Posix
decodeTime =
    Decode.int
        |> Decode.andThen
            (\ms ->
                Decode.succeed <| Time.millisToPosix ms
            )
Run Code Online (Sandbox Code Playgroud)