@@ -1,6 +1,8 @@
1{-# LANGUAGE CPP, DeriveDataTypeable, FlexibleContexts, FlexibleInstances,
1{-# LANGUAGE CPP, DeriveDataTypeable, FlexibleContexts, FlexibleInstances,
2 GeneralizedNewtypeDeriving, IncoherentInstances, OverlappingInstances,
2 GeneralizedNewtypeDeriving, IncoherentInstances, OverlappingInstances,
3− OverloadedStrings, UndecidableInstances, ViewPatterns #-}
3+ OverloadedStrings, UndecidableInstances, ViewPatterns,
4+ StandaloneDeriving #-}
5+{-# OPTIONS_GHC -fno-warn-orphans #-}
5#ifdef GENERICS
7#ifdef GENERICS
6{-# LANGUAGE DefaultSignatures #-}
8{-# LANGUAGE DefaultSignatures #-}
@@ -39,18 +41,18 @@ module Data.Aeson.Types.Class
39 , typeMismatch
41 , typeMismatch
42−import Control.Applicative ((<$>), (<*>), pure)
44+import Control.Applicative ((<$>), (<*>), (<|>), pure, empty)
43import Data.Aeson.Functions
45import Data.Aeson.Functions
44import Data.Aeson.Types.Internal
46import Data.Aeson.Types.Internal
45import Data.Attoparsec.Char8 (Number(..))
47import Data.Attoparsec.Char8 (Number(..))
46import Data.Hashable (Hashable(..))
48import Data.Hashable (Hashable(..))
47import Data.Int (Int8, Int16, Int32, Int64)
49import Data.Int (Int8, Int16, Int32, Int64)
48import Data.Maybe (fromMaybe)
50import Data.Maybe (fromMaybe)
49−import Data.Monoid (Dual(..), First(..), Last(..))
51+import Data.Monoid (Dual(..), First(..), Last(..), mappend)
50import Data.Ratio (Ratio)
52import Data.Ratio (Ratio)
51import Data.Text (Text, pack, unpack)
53import Data.Text (Text, pack, unpack)
52import Data.Text.Encoding (encodeUtf8)
54import Data.Text.Encoding (encodeUtf8)
53−import Data.Time.Clock (UTCTime)
55+import Data.Time (UTCTime, ZonedTime(..), TimeZone(..))
54import Data.Time.Format (FormatTime, formatTime, parseTime)
56import Data.Time.Format (FormatTime, formatTime, parseTime)
55import Data.Traversable (traverse)
57import Data.Traversable (traverse)
56import Data.Typeable (Typeable)
58import Data.Typeable (Typeable)
@@ -611,6 +613,37 @@ instance FromJSON DotNetTime where
611 parseJSON v = typeMismatch "DotNetTime" v
613 parseJSON v = typeMismatch "DotNetTime" v
612 {-# INLINE parseJSON #-}
614 {-# INLINE parseJSON #-}
616+deriving instance Eq ZonedTime
618+instance ToJSON ZonedTime where
619+ toJSON t = String $ pack $ formattedTime
622+ | 0 == timeZoneMinutes (zonedTimeZone t) =
623+ formatTime defaultTimeLocale "%FT%T%QZ" t
625+ formatTime defaultTimeLocale "%FT%T%Q%z" t
627+instance FromJSON ZonedTime where
628+ parseJSON (String t) =
629+ tryFormats alternateFormats
630+ <|> fail "could not parse ECMA-262 ISO-8601 date"
633+ case parseTime defaultTimeLocale f (unpack t) of
636+ tryFormats = foldr1 (<|>) . map tryFormat
638+ distributeList ["%Y", "%Y-%m", "%F"]
639+ ["T%R", "T%T", "T%T%Q", "T%T%QZ", "T%T%Q%z"]
641+ distributeList xs ys =
642+ foldr (\x acc -> acc ++ distribute x ys) [] xs
643+ distribute x = map (mappend x)
645+ parseJSON v = typeMismatch "ZonedTime" v
614instance ToJSON UTCTime where
647instance ToJSON UTCTime where
615 toJSON t = String (pack (take 23 str ++ "Z"))
648 toJSON t = String (pack (take 23 str ++ "Z"))
616 where str = formatTime defaultTimeLocale "%FT%T%Q" t
649 where str = formatTime defaultTimeLocale "%FT%T%Q" t