Elm: 将Json解码的时间戳转换为日期

16

我试图将一个JSON中的时间戳(例如:"1493287973015")转换为日期类型。

到目前为止,我创建了这个自定义解码器:

stringToDate : Decoder String -> Decoder Date
stringToDate decoder =
  customDecoder decoder Date.fromTime

但是它不起作用,因为它返回的是一个 Result 而不是 Date:

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

    Time.Time -> Result String a

But it is:

    Time.Time -> Date.Date

有没有一种方法可以进行转换?


如果它是UNIX时间戳,请记得将该值乘以1000。 - lifebalance
2个回答

20
假设你的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)
请注意,与您尝试将Decoder String作为参数传递的示例不同,stringToDate没有传递任何参数。解码器并非是这样使用的。
相反,在这种情况下,可以通过基于更原始的解码器来构建来完成这项任务,即从Json.Decode中的解码器string开始。
然后andThen部分获取解码器给出的字符串值,并尝试将其解析为浮点数。如果它是有效的Float,则将其传递到Date.fromTime中,否则它是一个失败。 failsucceed函数将您正在处理的常规值包装到Decoder Date.Date上下文中,以便可以返回它们。

1
谢谢!我已经搞定了。使用Elm解码JSON并不是一件容易的事情。 - Guilhem Soulas
3
我不会说它不容易。如果你来自一个命令式编程背景,这只是不熟悉而已。在函数式语言中,这种解析方式非常普遍,被称为“解析器组合器”。 - Chad Gilbert

6

两件事情,JSON 可能实际上具有毫秒作为一个整数,而不是字符串,自从 Elm 的版本 0.19 以来,情况已经发生了改变。

假设您的 JSON 看起来像这样。

{
    ...
    "someTime": 1552483995395,
    ...
}

那么这个会被解码为一个Time.Posix:
import Json.Decode as Decode

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

如果它是UNIX时间戳,请记得将该值乘以1000。 - lifebalance

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接