on master help sign in
Separate .NET and JavaScript date formats, per github issue 1
702616cBryan O'Sullivan
Data/Aeson.hs+2
@@ -15,6 +15,8 @@ module Data.Aeson
15 Value(..)
15 Value(..)
16 , Array
16 , Array
17 , Object
17 , Object
18+ -- * Convenience types
19+ , DotNetTime(..)
18 -- * Type conversion
20 -- * Type conversion
19 , FromJSON(..)
21 , FromJSON(..)
20 , Result(..)
22 , Result(..)
Data/Aeson/Generic.hs+2
@@ -71,6 +71,7 @@ toJSON = toJSON_generic
71 `extQ` (T.toJSON :: T B.ByteString)
71 `extQ` (T.toJSON :: T B.ByteString)
72 `extQ` (T.toJSON :: T L.ByteString)
72 `extQ` (T.toJSON :: T L.ByteString)
73 `extQ` (T.toJSON :: T T.Value)
73 `extQ` (T.toJSON :: T T.Value)
74+ `extQ` (T.toJSON :: T DotNetTime)
74 `extQ` (T.toJSON :: T UTCTime)
75 `extQ` (T.toJSON :: T UTCTime)
75 `extQ` (T.toJSON :: T IntSet)
76 `extQ` (T.toJSON :: T IntSet)
76 `extQ` (T.toJSON :: T Bool)
77 `extQ` (T.toJSON :: T Bool)
@@ -157,6 +158,7 @@ parseJSON j = parseJSON_generic j
157 `extR` (value :: F B.ByteString)
158 `extR` (value :: F B.ByteString)
158 `extR` (value :: F L.ByteString)
159 `extR` (value :: F L.ByteString)
159 `extR` (value :: F T.Value)
160 `extR` (value :: F T.Value)
161+ `extR` (value :: F DotNetTime)
160 `extR` (value :: F UTCTime)
162 `extR` (value :: F UTCTime)
161 `extR` (value :: F IntSet)
163 `extR` (value :: F IntSet)
162 `extR` (value :: F Bool)
164 `extR` (value :: F Bool)
Data/Aeson/Types.hs+25−7
@@ -1,5 +1,5 @@
1−{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, IncoherentInstances,
1+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, GeneralizedNewtypeDeriving,
2− OverlappingInstances, Rank2Types #-}
2+ IncoherentInstances, OverlappingInstances, Rank2Types #-}
3
3
4-- Module: Data.Aeson.Types
4-- Module: Data.Aeson.Types
5-- Copyright: (c) 2011 MailRank, Inc.
5-- Copyright: (c) 2011 MailRank, Inc.
@@ -19,6 +19,8 @@ module Data.Aeson.Types
19 , Pair
19 , Pair
20 , Object
20 , Object
21 , emptyObject
21 , emptyObject
22+ -- * Convenience types
23+ , DotNetTime(..)
22 -- * Type conversion
24 -- * Type conversion
23 , Parser
25 , Parser
24 , Result(..)
26 , Result(..)
@@ -46,7 +48,7 @@ import Data.Ratio (Ratio)
46import Data.Text (Text, pack, unpack)
48import Data.Text (Text, pack, unpack)
47import Data.Text.Encoding (decodeUtf8, encodeUtf8)
49import Data.Text.Encoding (decodeUtf8, encodeUtf8)
48import Data.Time.Clock (UTCTime)
50import Data.Time.Clock (UTCTime)
49−import Data.Time.Format (formatTime, parseTime)
51+import Data.Time.Format (FormatTime, formatTime, parseTime)
50import Data.Typeable (Typeable)
52import Data.Typeable (Typeable)
51import Data.Vector (Vector)
53import Data.Vector (Vector)
52import Data.Word (Word, Word8, Word16, Word32, Word64)
54import Data.Word (Word, Word8, Word16, Word32, Word64)
@@ -522,15 +524,31 @@ instance FromJSON Value where
522 parseJSON a = pure a
524 parseJSON a = pure a
523 {-# INLINE parseJSON #-}
525 {-# INLINE parseJSON #-}
524
526
525−-- We happen to use the same JSON formatting for a UTCTime as .NET
527+-- | A newtype wrapper for 'UTCTime' that uses the same non-standard
526−-- does for a DateTime. How handy!
528+-- serialization format as Microsoft .NET.
529+newtype DotNetTime = DotNetTime UTCTime
530+ deriving (Eq, Ord, Read, Show, Typeable, FormatTime)
531+
532+instance ToJSON DotNetTime where
533+ toJSON (DotNetTime t) =
534+ String (pack (formatTime defaultTimeLocale "/Date(%s)/" t))
535+ {-# INLINE toJSON #-}
536+
537+instance FromJSON DotNetTime where
538+ parseJSON (String t) =
539+ case parseTime defaultTimeLocale "/Date(%s)/" (unpack t) of
540+ Just d -> pure (DotNetTime d)
541+ _ -> empty
542+ parseJSON _ = empty
543+ {-# INLINE parseJSON #-}
544+
527instance ToJSON UTCTime where
545instance ToJSON UTCTime where
528− toJSON t = String (pack (formatTime defaultTimeLocale "/Date(%s)/" t))
546+ toJSON t = String (pack (formatTime defaultTimeLocale "%FT%X%QZ" t))
529 {-# INLINE toJSON #-}
547 {-# INLINE toJSON #-}
530
548
531instance FromJSON UTCTime where
549instance FromJSON UTCTime where
532 parseJSON (String t) =
550 parseJSON (String t) =
533− case parseTime defaultTimeLocale "/Date(%s)/" (unpack t) of
551+ case parseTime defaultTimeLocale "%FT%X%QZ" (unpack t) of
534 Just d -> pure d
552 Just d -> pure d
535 _ -> empty
553 _ -> empty
536 parseJSON _ = empty
554 parseJSON _ = empty