{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Data.Time.RFC3339 (
formatTimeRFC3339, formatDateRFC3339, parseTimeRFC3339, parseDateRFC3339
) where
import Control.Applicative
import Data.Maybe
import Data.Monoid ((<>))
import Data.Monoid.Textual hiding (foldr, map)
import Data.String (fromString)
import Data.Text (Text)
import Data.Time.Calendar
import Data.Time.Format
import Data.Time.LocalTime
import Data.Time.Util
formatTimeRFC3339 :: (TextualMonoid t) => ZonedTime -> t
formatTimeRFC3339 :: ZonedTime -> t
formatTimeRFC3339 zt :: ZonedTime
zt@(ZonedTime LocalTime
lt TimeZone
z) = String -> t
forall a. IsString a => String -> a
fromString (TimeLocale -> String -> ZonedTime -> String
forall t. FormatTime t => TimeLocale -> String -> t -> String
formatTime TimeLocale
defaultTimeLocale String
"%FT%T" ZonedTime
zt) t -> t -> t
forall a. Semigroup a => a -> a -> a
<> String -> t
forall a. IsString a => String -> a
fromString String
printZone
where timeZoneStr :: String
timeZoneStr = TimeZone -> String
timeZoneOffsetString TimeZone
z
printZone :: String
printZone = if String
timeZoneStr String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== TimeZone -> String
timeZoneOffsetString TimeZone
utc
then String
"Z"
else Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
3 String
timeZoneStr String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
":" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
3 String
timeZoneStr
formatDateRFC3339 :: (TextualMonoid t, FormatTime time) => time -> t
formatDateRFC3339 :: time -> t
formatDateRFC3339 time
day = String -> t
forall a. IsString a => String -> a
fromString (TimeLocale -> String -> time -> String
forall t. FormatTime t => TimeLocale -> String -> t -> String
formatTime TimeLocale
defaultTimeLocale String
"%F" time
day)
formatsRFC3339 :: [Text]
formatsRFC3339 :: [Text]
formatsRFC3339 = do
Text
fraction <- [Text
"%Q", Text
""]
Text
zone <- [Text
"Z", Text
"%z"]
Text -> [Text]
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> [Text]) -> Text -> [Text]
forall a b. (a -> b) -> a -> b
$ Text
"%FT%T" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
fraction Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
zone
parseTimeRFC3339 :: (TextualMonoid t) => t -> Maybe ZonedTime
parseTimeRFC3339 :: t -> Maybe ZonedTime
parseTimeRFC3339 = [Text] -> t -> Maybe ZonedTime
forall t t' time.
(TextualMonoid t, TextualMonoid t', ParseTime time) =>
[t] -> t' -> Maybe time
parseTimeUsing [Text]
formatsRFC3339
parseDateRFC3339 :: (TextualMonoid t) => t -> Maybe Day
parseDateRFC3339 :: t -> Maybe Day
parseDateRFC3339 = [Text] -> t -> Maybe Day
forall t t' time.
(TextualMonoid t, TextualMonoid t', ParseTime time) =>
[t] -> t' -> Maybe time
parseTimeUsing [Text
"%F" :: Text]