module Data.Convertible.Instances.Time()
where
import Data.Convertible.Base
import Data.Convertible.Utils
import Data.Convertible.Instances.Num()
import qualified System.Time as ST
import Data.Time
import Data.Time.Clock
import Data.Time.Clock.POSIX
import Data.Time.Calendar.OrdinalDate
import Data.Typeable
import Data.Ratio
instance Convertible ST.ClockTime ST.CalendarTime where
safeConvert = return . ST.toUTCTime
instance Convertible ST.CalendarTime ST.ClockTime where
safeConvert = return . ST.toClockTime
instance Convertible ST.ClockTime Integer where
safeConvert (ST.TOD x _) = return x
instance Convertible Integer ST.ClockTime where
safeConvert x = return $ ST.TOD x 0
instance Typeable NominalDiffTime where
typeOf _ = mkTypeName "NominalDiffTime"
instance Typeable UTCTime where
typeOf _ = mkTypeName "UTCTime"
instance Convertible Rational POSIXTime where
safeConvert = return . fromRational
instance Convertible Integer POSIXTime where
safeConvert = return . fromInteger
instance Convertible Int POSIXTime where
safeConvert = return . fromIntegral
instance Convertible Double POSIXTime where
safeConvert = return . fromRational . toRational
instance Convertible POSIXTime Integer where
safeConvert = return . truncate
instance Convertible POSIXTime Rational where
safeConvert = return . toRational
instance Convertible POSIXTime Double where
safeConvert = return . fromRational . toRational
instance Convertible POSIXTime Int where
safeConvert = boundedConversion (return . truncate)
instance Convertible POSIXTime UTCTime where
safeConvert = return . posixSecondsToUTCTime
instance Convertible UTCTime POSIXTime where
safeConvert = return . utcTimeToPOSIXSeconds
instance Convertible Rational UTCTime where
safeConvert a = safeConvert a >>= return . posixSecondsToUTCTime
instance Convertible Integer UTCTime where
safeConvert a = safeConvert a >>= return . posixSecondsToUTCTime
instance Convertible Int UTCTime where
safeConvert a = safeConvert a >>= return . posixSecondsToUTCTime
instance Convertible Double UTCTime where
safeConvert a = safeConvert a >>= return . posixSecondsToUTCTime
instance Convertible UTCTime Rational where
safeConvert = safeConvert . utcTimeToPOSIXSeconds
instance Convertible UTCTime Integer where
safeConvert = safeConvert . utcTimeToPOSIXSeconds
instance Convertible UTCTime Double where
safeConvert = safeConvert . utcTimeToPOSIXSeconds
instance Convertible UTCTime Int where
safeConvert = boundedConversion (safeConvert . utcTimeToPOSIXSeconds)
instance Convertible UTCTime ZonedTime where
safeConvert = return . utcToZonedTime utc
instance Convertible POSIXTime ZonedTime where
safeConvert = return . utcToZonedTime utc . posixSecondsToUTCTime
instance Convertible ZonedTime UTCTime where
safeConvert = return . zonedTimeToUTC
instance Convertible ZonedTime POSIXTime where
safeConvert = return . utcTimeToPOSIXSeconds . zonedTimeToUTC
instance Convertible ST.CalendarTime ZonedTime where
safeConvert ct = return $ ZonedTime {
zonedTimeToLocalTime = LocalTime {
localDay = fromGregorian (fromIntegral $ ST.ctYear ct)
(1 + (fromEnum $ ST.ctMonth ct))
(ST.ctDay ct),
localTimeOfDay = TimeOfDay {
todHour = ST.ctHour ct,
todMin = ST.ctMin ct,
todSec = (fromIntegral $ ST.ctSec ct) +
fromRational (ST.ctPicosec ct % 1000000000000)
}
},
zonedTimeZone = TimeZone {
timeZoneMinutes = ST.ctTZ ct `div` 60,
timeZoneSummerOnly = ST.ctIsDST ct,
timeZoneName = ST.ctTZName ct}
}
instance Convertible ST.CalendarTime POSIXTime where
safeConvert a = do r <- (safeConvert a)::ConvertResult ST.ClockTime
safeConvert r
instance Convertible ST.CalendarTime UTCTime where
safeConvert a = do r <- (safeConvert a)::ConvertResult POSIXTime
safeConvert r
instance Convertible ST.ClockTime POSIXTime where
safeConvert (ST.TOD x y) = return $ fromRational $
fromInteger x `plusorminus` fromRational (y % 1000000000000)
where plusorminus = if x < 0 then () else (+)
instance Convertible ST.ClockTime UTCTime where
safeConvert a = do r <- (safeConvert a)::ConvertResult POSIXTime
safeConvert r
instance Convertible ST.ClockTime ZonedTime where
safeConvert a = do r <- (safeConvert a)::ConvertResult UTCTime
safeConvert r
instance Convertible POSIXTime ST.ClockTime where
safeConvert x = return $ ST.TOD rsecs rpico
where rsecs = (truncate x :: Integer)
rpico = truncate $ abs $ 1000000000000 * (x (fromIntegral rsecs))
instance Convertible UTCTime ST.ClockTime where
safeConvert = safeConvert . utcTimeToPOSIXSeconds
instance Convertible ZonedTime ST.CalendarTime where
safeConvert zt = return $ ST.CalendarTime {
ST.ctYear = fromIntegral year,
ST.ctMonth = toEnum (month 1),
ST.ctDay = day,
ST.ctHour = todHour ltod,
ST.ctMin = todMin ltod,
ST.ctSec = secs,
ST.ctPicosec = truncate $ (((toRational (todSec ltod) (toRational secs)) * 1000000000000)::Rational),
ST.ctWDay = toEnum . snd . sundayStartWeek . localDay . zonedTimeToLocalTime $ zt,
ST.ctYDay = snd . toOrdinalDate . localDay . zonedTimeToLocalTime $ zt,
ST.ctTZName = timeZoneName . zonedTimeZone $ zt,
ST.ctTZ = (timeZoneMinutes . zonedTimeZone $ zt) * 60,
ST.ctIsDST = timeZoneSummerOnly . zonedTimeZone $ zt
}
where (year, month, day) = toGregorian . localDay . zonedTimeToLocalTime $ zt
ltod = localTimeOfDay . zonedTimeToLocalTime $ zt
secs = (truncate . todSec $ ltod)::Int
instance Convertible POSIXTime ST.CalendarTime where
safeConvert pt = do r <- (safeConvert pt)::ConvertResult ZonedTime
safeConvert r
instance Convertible UTCTime ST.CalendarTime where
safeConvert = safeConvert . utcTimeToPOSIXSeconds
instance Convertible ST.TimeDiff NominalDiffTime where
safeConvert td = safeConvert clockTime
where clockTime = ST.addToClockTime td (ST.TOD 0 0)
instance Convertible NominalDiffTime ST.TimeDiff where
safeConvert ndt =
do clockt <- safeConvert ndt
return (ST.diffClockTimes clockt (ST.TOD 0 0))