首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ZonedTime fromJSON toJSON

ZonedTime fromJSON toJSON
EN

Stack Overflow用户
提问于 2016-12-22 12:22:41
回答 2查看 207关注 0票数 1

我被ZonedTimeAesonServant转换搞糊涂了。

对于我的Servant应用程序,我在url:.../2016-12-18T07:51:00+03:00/...中提供了一些时间。

Servant可以使用... :> Capture "zt" ZonedTime :> ...轻松地将其转换为ZonedTime

然后我的应用程序做了一些计算,在json-ZonedTime中,我想要将这个时间和其他一些响应时间返回给客户端-以防客户端再次将这些时间提供给我的应用程序。

如果输入时区不是零+0X:00 (X /= 0),那么在输出上我也会得到+0X:00,但如果在输入上我给出了.../2016-12-18T07:51:00+00:00/...,那么作为响应,我会得到2016-12-18T07:51:00Z。如果我再次尝试使用.../2016-12-18T07:51:00Z/...将此字符串提供给Servant,则Servant无法将其转换为ZonedTime。实际上是返回HTTP 400 (Bad Request)

为什么?干什么用?For what?

EN

回答 2

Stack Overflow用户

发布于 2016-12-23 05:09:31

ISO 8601是JSON中使用的时间的标准文本表示。当时区为UTC时,"+00:00“或"Z”是有效的时区后缀。在ISO 8601中,如果是UTC,则使用"Z“后缀输出时间,否则使用"+xx:xx”后缀。不幸的是,Servant (实际上是Web.HttpApiData)使用了一种简单的方法,从不允许使用"Z“后缀的URL片段中解析ZonedTime。如果您解析UTCTime,那么它将使用(并且需要) "Z“后缀。

您可以按如下方式为ZonedTime定义一个新类型别名,通过尝试将其解析为ZonedTime并(如果解析失败)解析为具有转换功能的UTCTime来处理这两种格式:

代码语言:javascript
复制
module ZonedTimeTest where

import Data.Time.LocalTime
import Servant.API

newtype ZonedTime' = ZonedTime' { getZonedTime :: ZonedTime }

instance FromHttpApiData ZonedTime' where
  parseUrlPiece u =     ZonedTime' <$> parseUrlPiece u            -- "...+xx:xx"
                    <!> ZonedTime' . fromUTC <$> parseUrlPiece u  -- "...Z"
    where fromUTC = utcToZonedTime utc
          infixl 3 <!>
          Left _ <!> y = y
          x      <!> _ = x

然后,Capture "zt" ZonedTime'应该为您处理这两种格式(尽管您需要在适当的地方将ZonedTime'解包为ZonedTime )。

票数 0
EN

Stack Overflow用户

发布于 2016-12-23 08:22:38

好的。

所以,一旦Servant正确地将...Z符号解析为UTCTime,我就编写了另一行捕获代码:

代码语言:javascript
复制
:<|> "myendpoint" :> Capture "zt" ZonedTime :> ...
:<|> "myendpoint" :> Capture "utct" UTCTime :> ...

并制定了相应的处理程序。使用这个带有+xx:xx的字面值作为ZonedTime并转到一个处理程序,使用Z的字面值由第二行获取并转到第二个处理程序,这与第一个处理程序的功能相同,但会动态地将UTC转换为Zoned

更新

我开始明白,我的系统是如何工作的,这导致了这样一个事实,在URL中,我可能有不同的字符串编码时间。

作为时区的

  1. 可以是+03:00,如果是用于协调世界时,则仅为Z
  2. I可能像2016-12-09T15:04:26.349857693845+05:00

一样具有小数秒

ZonedTime的标准Capture既不能将Z理解为时区,也不能理解为小数秒。

因此,我以某种方式朝这个方向做了,就像这里的另一个答案所建议的那样。

我只放了一条捕获线

代码语言:javascript
复制
"daymonth" :> Capture "zt" ZonedTime' :> Capture "fl" Double :> Get '[JSON] Value

我制作了新的ZonedTime',它为我做了所有的事情。

代码语言:javascript
复制
newtype ZonedTime' = ZonedTime' { unwrap :: ZonedTime }

instance FromHttpApiData ZonedTime' where
  parseUrlPiece text = Right zt
    where
      strRaw = unpack text
      str = subRegex (mkRegex "Z$") strRaw "+00:00"
      zt = ZonedTime' (parseTimeOrError False defaultTimeLocale "%Y-%m-%dT%H:%M:%S%Q%z" str)

我处理字符串问题,将其替换为+00:00

  • Then。我手动编写字符串的解析,给出格式字符串,其中%Q捕获秒的小数部分。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41275758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档