-- | convert between 'UTCTime' and 'DatePart' module Data.Time.Hora.Part (fromUtc,fromUtc', ToUTC(..)) where import Data.Time.Hora.Type import Data.Time.Hora.Span import Data.Time.Clock import Data.Time.Calendar import Data.Time.LocalTime as L import Data.Fixed {- | UTC -} fromUtc::Integral a => UTCTime -> DatePart a fromUtc t0 = let day1 = utctDay t0::Day dt1 = utctDayTime t0::DiffTime (y1,m1,d1) = toGregorian day1 tod1 = timeToTimeOfDay dt1::TimeOfDay pico4 = todSec tod1::Fixed E12 (sec5, MkFixed pico5) = properFraction pico4 in DatePart { year = fi y1, month = fi m1, day = fi d1, hour = fi $ todHour tod1, minute = fi $ todMin tod1, second = fi sec5, pico = fi pico5 } {- | specified time zone Tz (DatePart a) parts show local date & time see also "Data.Time.Hora.Zone" -} fromUtc'::(Tz' tz, Integral a) => tz -> UTCTime -> Tz (DatePart a) fromUtc' tz0 utc0 = let tz1 = tz' tz0 utc0 lt2 = L.utcToLocalTime tz1 utc0 day2 = localDay lt2 time2 = localTimeOfDay lt2 (y3,m3,d3) = toGregorian day2 d4 = DatePart{ year = fi y3, month = fi m3, day = fi d3, hour = fi $ todHour time2, minute = fi $ todMin time2, second = fi sec5, pico = fi pico5 } pico4 = todSec time2::Fixed E12 (sec5, MkFixed pico5) = properFraction pico4 in Tz tz1 d4 {-| convert 'DatePart' -> 'UTCTime' Invalid date returns Nothing -} class ToUTC a where toUtc::a -> Maybe UTCTime instance Integral a => ToUTC (DatePart a) where toUtc dp0 = let h1 = hour dp0 * 60 * 60 -- as second min1 = minute dp0 * 60 -- as second s2 = second dp0 + h1 + min1 diff1 = secondsToDiffTime $ fi s2 diff2 = picosecondsToDiffTime $ fi $ pico dp0 mday1 = fromGregorianValid (fi $ year dp0) (fi $ month dp0) $ fi $ day dp0 in mday1 >>= \day1 -> Just $ UTCTime day1 $ diff1 + diff2 -- ^ assumes DatePart is UTC instance Integral a => ToUTC (Tz (DatePart a)) where toUtc (Tz tz0 dp0) = let s1 = toPico $ Sec $ second dp0 mtod1 = makeTimeOfDayValid (fi $ hour dp0) (fi $ minute dp0) (timeSpanPico $ Pico s1 + (Pico $ fi $ pico dp0)) mday1 = fromGregorianValid (fi $ year dp0) (fi $ month dp0) $ fi $ day dp0 in mday1 >>= \day1 -> mtod1 >>= \tod1 -> let lt1 = LocalTime day1 tod1 zt1 = ZonedTime lt1 tz0 in Just $ zonedTimeToUTC zt1 fi::TwoInt a b => a -> b fi = fromIntegral