{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeSynonymInstances #-} module Data.Time.Parsers.Types where import Control.Monad.Reader (ReaderT) import Data.Attoparsec.Char8 (Parser) import Data.Convertible import Data.Convertible.Instances() import qualified Data.Set as Set import Data.Time import Data.Time.Clock.POSIX -- | A type that can be converted from ZonedTime class FromZonedTime a where fromZonedTime :: ZonedTime -> a instance FromZonedTime ZonedTime where fromZonedTime = id instance FromZonedTime LocalTime where fromZonedTime = zonedTimeToLocalTime instance FromZonedTime Day where fromZonedTime = localDay . fromZonedTime instance FromZonedTime UTCTime where fromZonedTime = zonedTimeToUTC instance FromZonedTime POSIXTime where fromZonedTime = convert -- | A type that can be converted to ZonedTime -- For LocalTime, it is assumed the TimeZone is UTC -- For Day, it is assumed that the TimeOfDay is midnight and the TimeZone is UTC class ToZonedTime a where toZonedTime :: a -> ZonedTime instance ToZonedTime ZonedTime where toZonedTime = id instance ToZonedTime LocalTime where toZonedTime = flip ZonedTime utc instance ToZonedTime Day where toZonedTime = toZonedTime . flip LocalTime midnight instance ToZonedTime UTCTime where toZonedTime = utcToZonedTime utc instance ToZonedTime POSIXTime where toZonedTime = convert -- | Formats for purely numeric dates, e.g. 99-2-27 data DateFormat = YMD -- ^ year-month-day | MDY -- ^ month-year-day | DMY -- ^ day-month-year deriving (Eq, Show) -- | Flags to tune the behavior of a parser data Flag = MakeRecent -- ^ Interpret years 0-99 as 1970-2069 | DefaultToMidnight -- ^ If no TimeOfDay is supplied for a type where it -- is required, use midnight | DefaultToUTC -- ^ If no timezone is supplied for a type where it -- is required, use UTC | RequirePosixUnit -- ^ Require an 's' at the end of a POSIX timestamp. -- Can be used to distinguish between POSIXTime and -- iso8601 with no separators. | AustralianTimeZones -- ^ Use Australian Timezones deriving (Eq,Ord,Show) data Options = Options { formats :: [DateFormat] -- ^ List of what DateFormats to try. , seps :: String -- ^ Set of accepted separators , flags :: Set.Set Flag -- ^ Set of Flags } -- | A Parser with Options type OptionedParser a = ReaderT Options Parser a data DateToken = Year Integer -- ^ An Integer that is known to represent a year | Month Integer -- ^ An Integer that is known to represent a month | Any Integer -- ^ An Integer that could represent a day, month, or year deriving (Eq, Show) data ExtendedTimestamp a = Timestamp a -- ^ An explicit Timestamp | Now -- ^ The current time | Yesterday -- ^ Midnight yesterday | Today -- ^ Midnight today | Tomorrow -- ^ Midight tomorrow deriving (Eq, Show)