penny-lib-0.2.0.0: Penny/Lincoln/Bits/DateTime.hs
-- | Perhaps this could be called @moment@, as it aims to identify a
-- moment in time. A DateTime is a combination of a LocalTime from
-- Data.Time and a TimeZoneOffset. Previously a DateTime was simply a
-- ZonedTime from Data.Time but ZonedTime has data that Penny does not
-- need.
module Penny.Lincoln.Bits.DateTime (
DateTime
, dateTime
, localTime
, timeZone
, TimeZoneOffset
, offsetToMins
, minsToOffset
, noOffset
) where
import qualified Data.Time as T
-- | The number of minutes that this timezone is offset from UTC. Can
-- be positive, negative, or zero.
newtype TimeZoneOffset = TimeZoneOffset { offsetToMins :: Int }
deriving (Eq, Ord, Show)
-- | Convert minutes to a time zone offset. I'm having a hard time
-- deciding whether to be liberal or strict in what to accept
-- here. Currently it is somewhat strict in that it will fail if
-- absolute value is greater than 840 minutes; currently the article
-- at http://en.wikipedia.org/wiki/List_of_time_zones_by_UTC_offset
-- says there is no offset greater than 14 hours, or 840 minutes.
minsToOffset :: Int -> Maybe TimeZoneOffset
minsToOffset m = if abs m > 840
then Nothing
else Just $ TimeZoneOffset m
noOffset :: TimeZoneOffset
noOffset = TimeZoneOffset 0
-- | A DateTime is a UTC time that also remembers the local time from
-- which it was set. The Eq and Ord instances will compare two
-- DateTimes based on their equivalent UTC times.
data DateTime = DateTime { localTime :: T.LocalTime
, timeZone :: TimeZoneOffset }
deriving Show
-- | Construct a DateTime.
dateTime :: T.LocalTime -> TimeZoneOffset -> DateTime
dateTime = DateTime
toUTC :: DateTime -> T.UTCTime
toUTC (DateTime lt (TimeZoneOffset tzo)) = T.localTimeToUTC tz lt where
tz = T.minutesToTimeZone tzo
instance Eq DateTime where
l == r = toUTC l == toUTC r
instance Ord DateTime where
compare l r = compare (toUTC l) (toUTC r)