Bryan O'Sullivan avatar Bryan O'Sullivan committed c156c14

Separate .NET and JavaScript date formats, per github issue 1

Comments (0)

Files changed (3)

       Value(..)
     , Array
     , Object
+    -- * Convenience types
+    , DotNetTime(..)
     -- * Type conversion
     , FromJSON(..)
     , Result(..)

Data/Aeson/Generic.hs

          `extQ` (T.toJSON :: T B.ByteString)
          `extQ` (T.toJSON :: T L.ByteString)
          `extQ` (T.toJSON :: T T.Value)
+         `extQ` (T.toJSON :: T DotNetTime)
          `extQ` (T.toJSON :: T UTCTime)
          `extQ` (T.toJSON :: T IntSet)
          `extQ` (T.toJSON :: T Bool)
              `extR` (value :: F B.ByteString)
              `extR` (value :: F L.ByteString)
              `extR` (value :: F T.Value)
+             `extR` (value :: F DotNetTime)
              `extR` (value :: F UTCTime)
              `extR` (value :: F IntSet)
              `extR` (value :: F Bool)

Data/Aeson/Types.hs

-{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, IncoherentInstances,
-    OverlappingInstances, Rank2Types #-}
+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, GeneralizedNewtypeDeriving,
+    IncoherentInstances, OverlappingInstances, Rank2Types #-}
 
 -- Module:      Data.Aeson.Types
 -- Copyright:   (c) 2011 MailRank, Inc.
     , Pair
     , Object
     , emptyObject
+    -- * Convenience types
+    , DotNetTime(..)
     -- * Type conversion
     , Parser
     , Result(..)
 import Data.Text (Text, pack, unpack)
 import Data.Text.Encoding (decodeUtf8, encodeUtf8)
 import Data.Time.Clock (UTCTime)
-import Data.Time.Format (formatTime, parseTime)
+import Data.Time.Format (FormatTime, formatTime, parseTime)
 import Data.Typeable (Typeable)
 import Data.Vector (Vector)
 import Data.Word (Word, Word8, Word16, Word32, Word64)
     parseJSON a = pure a
     {-# INLINE parseJSON #-}
 
--- We happen to use the same JSON formatting for a UTCTime as .NET
--- does for a DateTime. How handy!
+-- | A newtype wrapper for 'UTCTime' that uses the same non-standard
+-- serialization format as Microsoft .NET.
+newtype DotNetTime = DotNetTime UTCTime
+    deriving (Eq, Ord, Read, Show, Typeable, FormatTime)
+
+instance ToJSON DotNetTime where
+    toJSON (DotNetTime t) =
+        String (pack (formatTime defaultTimeLocale "/Date(%s)/" t))
+    {-# INLINE toJSON #-}
+
+instance FromJSON DotNetTime where
+    parseJSON (String t) =
+        case parseTime defaultTimeLocale "/Date(%s)/" (unpack t) of
+          Just d -> pure (DotNetTime d)
+          _      -> empty
+    parseJSON _          = empty
+    {-# INLINE parseJSON #-}
+
 instance ToJSON UTCTime where
-    toJSON t = String (pack (formatTime defaultTimeLocale "/Date(%s)/" t))
+    toJSON t = String (pack (formatTime defaultTimeLocale "%FT%X%QZ" t))
     {-# INLINE toJSON #-}
 
 instance FromJSON UTCTime where
     parseJSON (String t) =
-        case parseTime defaultTimeLocale "/Date(%s)/" (unpack t) of
+        case parseTime defaultTimeLocale "%FT%X%QZ" (unpack t) of
           Just d -> pure d
           _      -> empty
     parseJSON _          = empty
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.