{-# LANGUAGE OverloadedStrings #-} module Chronos.Datetime.ByteString.Char7 where import Chronos.Types import Data.ByteString (ByteString) import Data.ByteString.Builder (Builder) import Data.Vector (Vector) import Data.Monoid import Data.Attoparsec.ByteString (Parser) import Control.Monad import Data.Foldable import qualified Chronos.Date.ByteString.Char7 as Date import qualified Chronos.TimeOfDay.ByteString.Char7 as TimeOfDay import qualified Data.ByteString.Char8 as ByteString import qualified Data.ByteString.Lazy.Char8 as LByteString import qualified Data.Attoparsec.ByteString.Char8 as Atto import qualified Data.Vector as Vector import qualified Data.ByteString.Lazy.Builder as Builder encode_YmdHMS :: SubsecondPrecision -> DatetimeFormat -> Datetime -> ByteString encode_YmdHMS sp format = LByteString.toStrict . Builder.toLazyByteString . builder_YmdHMS sp format encode_YmdIMS_p :: MeridiemLocale ByteString -> SubsecondPrecision -> DatetimeFormat -> Datetime -> ByteString encode_YmdIMS_p a sp b = LByteString.toStrict . Builder.toLazyByteString . builder_YmdIMS_p a sp b -- | This could be written much more efficiently since we know the -- exact size the resulting 'ByteString' will be. builder_YmdHMS :: SubsecondPrecision -> DatetimeFormat -> Datetime -> Builder builder_YmdHMS sp (DatetimeFormat mdateSep msep mtimeSep) (Datetime date time) = case msep of Nothing -> Date.builder_Ymd mdateSep date <> TimeOfDay.builder_HMS sp mtimeSep time Just sep -> Date.builder_Ymd mdateSep date <> Builder.char7 sep <> TimeOfDay.builder_HMS sp mtimeSep time builder_YmdIMS_p :: MeridiemLocale ByteString -> SubsecondPrecision -> DatetimeFormat -> Datetime -> Builder builder_YmdIMS_p locale sp (DatetimeFormat mdateSep msep mtimeSep) (Datetime date time) = Date.builder_Ymd mdateSep date <> maybe mempty Builder.char7 msep <> TimeOfDay.builder_IMS_p locale sp mtimeSep time builder_YmdIMSp :: MeridiemLocale ByteString -> SubsecondPrecision -> DatetimeFormat -> Datetime -> Builder builder_YmdIMSp locale sp (DatetimeFormat mdateSep msep mtimeSep) (Datetime date time) = Date.builder_Ymd mdateSep date <> maybe mempty Builder.char7 msep <> TimeOfDay.builder_IMS_p locale sp mtimeSep time builderW3 :: Datetime -> Builder builderW3 = builder_YmdHMS SubsecondPrecisionAuto (DatetimeFormat (Just '-') (Just 'T') (Just ':')) decode_YmdHMS :: DatetimeFormat -> ByteString -> Maybe Datetime decode_YmdHMS format = either (const Nothing) Just . Atto.parseOnly (parser_YmdHMS format) parser_YmdHMS :: DatetimeFormat -> Parser Datetime parser_YmdHMS (DatetimeFormat mdateSep msep mtimeSep) = do date <- Date.parser_Ymd mdateSep traverse_ Atto.char msep time <- TimeOfDay.parser_HMS mtimeSep return (Datetime date time) parser_YmdHMS_opt_S :: DatetimeFormat -> Parser Datetime parser_YmdHMS_opt_S (DatetimeFormat mdateSep msep mtimeSep) = do date <- Date.parser_Ymd mdateSep traverse_ Atto.char msep time <- TimeOfDay.parser_HMS_opt_S mtimeSep return (Datetime date time) decode_YmdHMS_opt_S :: DatetimeFormat -> ByteString -> Maybe Datetime decode_YmdHMS_opt_S format = either (const Nothing) Just . Atto.parseOnly (parser_YmdHMS_opt_S format)