Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Aeson中编写JSON日期数据的自定义实例_Json_Haskell_Aeson - Fatal编程技术网

在Aeson中编写JSON日期数据的自定义实例

在Aeson中编写JSON日期数据的自定义实例,json,haskell,aeson,Json,Haskell,Aeson,我有以下格式的JSON日期数据: {"date": "2015-04-12"} 以及相应的haskell类型: data Date = Date { year :: Int , month :: Int , day :: Int } 如何为 图书馆 由于格式问题,派生实例不起作用。您必须将y/m/d转换为字符串或从字符串转换为字符串 {-# LANGUAGE OverloadedStrings #-} {-# OPTIONS_GHC -fn

我有以下格式的JSON日期数据:

  {"date": "2015-04-12"}
以及相应的haskell类型:

data Date = Date {
      year   :: Int
    , month  :: Int
    , day    :: Int
    }
如何为 图书馆
由于格式问题,派生实例不起作用。

您必须将y/m/d转换为字符串或从字符串转换为字符串

{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-tabs #-}

import Control.Monad
import Data.Aeson
import qualified Data.Text as T
import Text.Read (readMaybe)
-- import qualified Data.Attoparsec.Text as A

data Date = Date Int Int Int deriving (Read, Show)

instance ToJSON Date where
    toJSON (Date y m d) = toJSON $ object [
        "date" .= T.pack (str 4 y ++ "-" ++ str 2 m ++ "-" ++ str 2 d)]
        where
            str n = pad . show where
                pad s = replicate (n - length s) '0' ++ s

instance FromJSON Date where
    parseJSON = withObject "date" $ \v -> do
        str <- v .: "date"
        let
            ps@(~[y, m, d]) = T.split (== '-') str
        guard (length ps == 3)
        Date <$> readNum y <*> readNum m <*> readNum d
        where
            readNum = maybe (fail "not num") return . readMaybe . T.unpack

    -- -- or with attoparsec
    -- parseJSON = withObject "date" $ \v -> do
    --  str <- v .: "date"
    --  [y, m, d] <- either fail return $
    --      A.parseOnly (A.decimal `A.sepBy` A.char '-') str
    --  return $ Date y m d

为什么要重新发明轮子?包中的日期有一个半标准的表示形式,称为。它变得更好了:不仅同一个包甚至还提供了用于解析Day的实用程序,这些实用程序甚至可以导出到aeson。是的,aeson中已经有ToJSON和FromJSON实例:

如果您真的想提取天数、月份和年份,可以随时使用。不过,坚持标准抽象可能是一个很好的长期选择

ghci> :set -XOverloadedStrings
ghci> import Data.Time.Calendar
ghci> import Data.Aeson
ghci> fromJSON "2015-04-12" :: Result Day
Success 2015-04-12
ghci> toJSON (fromGregorian 2015 4 12)
String "2015-04-12"