Permalink
Browse files

Add a TimeWithZone newtype, similar to the DotNetTime newtype, wrappi…

…ng the default time format generated by Rails.
  • Loading branch information...
1 parent 017fdb4 commit e3894cc271dd9e7f57cefbd425cf4bd915c69c81 @mike-burns committed Dec 29, 2011
Showing with 22 additions and 0 deletions.
  1. +1 −0 Data/Aeson/Types.hs
  2. +21 −0 Data/Aeson/Types/Class.hs
View
@@ -22,6 +22,7 @@ module Data.Aeson.Types
, emptyObject
-- * Convenience types and functions
, DotNetTime(..)
+ , TimeWithZone(..)
, typeMismatch
-- * Type conversion
, Parser
View
@@ -30,6 +30,7 @@ module Data.Aeson.Types.Class
#endif
-- * Types
, DotNetTime(..)
+ , TimeWithZone(..)
-- * Functions
, fromJSON
, (.:)
@@ -611,6 +612,26 @@ instance FromJSON DotNetTime where
parseJSON v = typeMismatch "DotNetTime" v
{-# INLINE parseJSON #-}
+-- | A newtype wrapper for 'UTCTime' that uses the same ISO-8601 format that
+-- Rails uses by default for its TimeWithZone type. The time format is
+-- @%FT%T%Z@, which is one of the many allowed variants of ISO-8601.
+newtype TimeWithZone = TimeWithZone {
+ fromTimeWithZone :: UTCTime
+ } deriving (Eq, Ord, Read, Show, Typeable, FormatTime)
+
+instance ToJSON TimeWithZone where
+ toJSON t = String (pack str)
+ where str = formatTime defaultTimeLocale "%FT%T%Z" t
+ {-# INLINE toJSON #-}
+
+instance FromJSON TimeWithZone where
+ parseJSON (String t) =
+ case parseTime defaultTimeLocale "%FT%T%Z" (unpack t) of
+ Just d -> pure $ TimeWithZone d
+ _ -> fail "could not parse ISO-8601 date from Rails default format"
+ parseJSON v = typeMismatch "UTCTime" v
+ {-# INLINE parseJSON #-}
+
instance ToJSON UTCTime where
toJSON t = String (pack (take 23 str ++ "Z"))
where str = formatTime defaultTimeLocale "%FT%T%Q" t

0 comments on commit e3894cc

Please sign in to comment.