{- |
   Module     : Data.Convertible.Instances.Time
   Copyright  : Copyright (C) 2009-2011 John Goerzen
   License    : BSD3

   Maintainer : John Goerzen <jgoerzen@complete.org>
   Stability  : provisional
   Portability: portable

Instances to convert between various time structures, both old- and new-style.

At present, this module does not do full input validation.  That is, it is possible
to get an exception rather than a Left result from these functions if your input is
invalid, particularly when converting from the old-style System.Time structures.

Copyright (C) 2009-2011 John Goerzen <jgoerzen@complete.org>

All rights reserved.

For license and copyright information, see the file LICENSE

-}

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.POSIX
import Data.Time.Calendar.OrdinalDate
import Data.Ratio
import Foreign.C.Types

----------------------------------------------------------------------
-- Intra-System.Time stuff
----------------------------------------------------------------------

instance Convertible ST.ClockTime ST.CalendarTime where
    safeConvert :: ClockTime -> ConvertResult CalendarTime
safeConvert = CalendarTime -> ConvertResult CalendarTime
forall (m :: * -> *) a. Monad m => a -> m a
return (CalendarTime -> ConvertResult CalendarTime)
-> (ClockTime -> CalendarTime)
-> ClockTime
-> ConvertResult CalendarTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ClockTime -> CalendarTime
ST.toUTCTime

instance Convertible ST.CalendarTime ST.ClockTime where
    safeConvert :: CalendarTime -> ConvertResult ClockTime
safeConvert = ClockTime -> ConvertResult ClockTime
forall (m :: * -> *) a. Monad m => a -> m a
return (ClockTime -> ConvertResult ClockTime)
-> (CalendarTime -> ClockTime)
-> CalendarTime
-> ConvertResult ClockTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CalendarTime -> ClockTime
ST.toClockTime

instance Convertible ST.ClockTime Integer where
    safeConvert :: ClockTime -> ConvertResult Integer
safeConvert (ST.TOD Integer
x Integer
_) = Integer -> ConvertResult Integer
forall (m :: * -> *) a. Monad m => a -> m a
return Integer
x

instance Convertible Integer ST.ClockTime where
    safeConvert :: Integer -> ConvertResult ClockTime
safeConvert Integer
x = ClockTime -> ConvertResult ClockTime
forall (m :: * -> *) a. Monad m => a -> m a
return (ClockTime -> ConvertResult ClockTime)
-> ClockTime -> ConvertResult ClockTime
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> ClockTime
ST.TOD Integer
x Integer
0

----------------------------------------------------------------------
-- Intra-Data.Time stuff
----------------------------------------------------------------------

------------------------------ POSIX and UTC times
{- Covered under Real a
instance Convertible Rational POSIXTime where
    safeConvert = return . fromRational
-}

instance Convertible Rational POSIXTime where
    safeConvert :: Rational -> ConvertResult POSIXTime
safeConvert = POSIXTime -> ConvertResult POSIXTime
forall (m :: * -> *) a. Monad m => a -> m a
return (POSIXTime -> ConvertResult POSIXTime)
-> (Rational -> POSIXTime) -> Rational -> ConvertResult POSIXTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> POSIXTime
forall a. Fractional a => Rational -> a
fromRational
instance Convertible Integer POSIXTime where
    safeConvert :: Integer -> ConvertResult POSIXTime
safeConvert = POSIXTime -> ConvertResult POSIXTime
forall (m :: * -> *) a. Monad m => a -> m a
return (POSIXTime -> ConvertResult POSIXTime)
-> (Integer -> POSIXTime) -> Integer -> ConvertResult POSIXTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> POSIXTime
forall a. Num a => Integer -> a
fromInteger
instance Convertible Int POSIXTime where
    safeConvert :: Int -> ConvertResult POSIXTime
safeConvert = POSIXTime -> ConvertResult POSIXTime
forall (m :: * -> *) a. Monad m => a -> m a
return (POSIXTime -> ConvertResult POSIXTime)
-> (Int -> POSIXTime) -> Int -> ConvertResult POSIXTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> POSIXTime
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance Convertible Double POSIXTime where
    safeConvert :: Double -> ConvertResult POSIXTime
safeConvert = POSIXTime -> ConvertResult POSIXTime
forall (m :: * -> *) a. Monad m => a -> m a
return (POSIXTime -> ConvertResult POSIXTime)
-> (Double -> POSIXTime) -> Double -> ConvertResult POSIXTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> POSIXTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac

instance Convertible POSIXTime Integer where
    safeConvert :: POSIXTime -> ConvertResult Integer
safeConvert = Integer -> ConvertResult Integer
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> ConvertResult Integer)
-> (POSIXTime -> Integer) -> POSIXTime -> ConvertResult Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate
instance Convertible POSIXTime Rational where
    safeConvert :: POSIXTime -> ConvertResult Rational
safeConvert = Rational -> ConvertResult Rational
forall (m :: * -> *) a. Monad m => a -> m a
return (Rational -> ConvertResult Rational)
-> (POSIXTime -> Rational) -> POSIXTime -> ConvertResult Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> Rational
forall a. Real a => a -> Rational
toRational
instance Convertible POSIXTime Double where
    safeConvert :: POSIXTime -> ConvertResult Double
safeConvert = Double -> ConvertResult Double
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> ConvertResult Double)
-> (POSIXTime -> Double) -> POSIXTime -> ConvertResult Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac
instance Convertible POSIXTime Int where
    safeConvert :: POSIXTime -> ConvertResult Int
safeConvert = (POSIXTime -> ConvertResult Int) -> POSIXTime -> ConvertResult Int
forall b a.
(Bounded b, Show a, Show b, Convertible a Integer,
 Convertible b Integer, Typeable a, Typeable b) =>
(a -> ConvertResult b) -> a -> ConvertResult b
boundedConversion (Int -> ConvertResult Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> ConvertResult Int)
-> (POSIXTime -> Int) -> POSIXTime -> ConvertResult Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> Int
forall a b. (RealFrac a, Integral b) => a -> b
truncate)

instance Convertible POSIXTime UTCTime where
    safeConvert :: POSIXTime -> ConvertResult UTCTime
safeConvert = UTCTime -> ConvertResult UTCTime
forall (m :: * -> *) a. Monad m => a -> m a
return (UTCTime -> ConvertResult UTCTime)
-> (POSIXTime -> UTCTime) -> POSIXTime -> ConvertResult UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> UTCTime
posixSecondsToUTCTime
instance Convertible UTCTime POSIXTime where
    safeConvert :: UTCTime -> ConvertResult POSIXTime
safeConvert = POSIXTime -> ConvertResult POSIXTime
forall (m :: * -> *) a. Monad m => a -> m a
return (POSIXTime -> ConvertResult POSIXTime)
-> (UTCTime -> POSIXTime) -> UTCTime -> ConvertResult POSIXTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> POSIXTime
utcTimeToPOSIXSeconds

instance Convertible Rational UTCTime where
    safeConvert :: Rational -> ConvertResult UTCTime
safeConvert Rational
a = POSIXTime -> UTCTime
posixSecondsToUTCTime (POSIXTime -> UTCTime)
-> ConvertResult POSIXTime -> ConvertResult UTCTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Rational -> ConvertResult POSIXTime
forall a b. Convertible a b => a -> ConvertResult b
safeConvert Rational
a
instance Convertible Integer UTCTime where
    safeConvert :: Integer -> ConvertResult UTCTime
safeConvert Integer
a = POSIXTime -> UTCTime
posixSecondsToUTCTime (POSIXTime -> UTCTime)
-> ConvertResult POSIXTime -> ConvertResult UTCTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Integer -> ConvertResult POSIXTime
forall a b. Convertible a b => a -> ConvertResult b
safeConvert Integer
a
instance Convertible Int UTCTime where
    safeConvert :: Int -> ConvertResult UTCTime
safeConvert Int
a = POSIXTime -> UTCTime
posixSecondsToUTCTime (POSIXTime -> UTCTime)
-> ConvertResult POSIXTime -> ConvertResult UTCTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> ConvertResult POSIXTime
forall a b. Convertible a b => a -> ConvertResult b
safeConvert Int
a
instance Convertible Double UTCTime where
    safeConvert :: Double -> ConvertResult UTCTime
safeConvert Double
a = POSIXTime -> UTCTime
posixSecondsToUTCTime (POSIXTime -> UTCTime)
-> ConvertResult POSIXTime -> ConvertResult UTCTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Double -> ConvertResult POSIXTime
forall a b. Convertible a b => a -> ConvertResult b
safeConvert Double
a

instance Convertible UTCTime Rational where
    safeConvert :: UTCTime -> ConvertResult Rational
safeConvert = POSIXTime -> ConvertResult Rational
forall a b. Convertible a b => a -> ConvertResult b
safeConvert (POSIXTime -> ConvertResult Rational)
-> (UTCTime -> POSIXTime) -> UTCTime -> ConvertResult Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> POSIXTime
utcTimeToPOSIXSeconds
instance Convertible UTCTime Integer where
    safeConvert :: UTCTime -> ConvertResult Integer
safeConvert = POSIXTime -> ConvertResult Integer
forall a b. Convertible a b => a -> ConvertResult b
safeConvert (POSIXTime -> ConvertResult Integer)
-> (UTCTime -> POSIXTime) -> UTCTime -> ConvertResult Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> POSIXTime
utcTimeToPOSIXSeconds
instance Convertible UTCTime Double where
    safeConvert :: UTCTime -> ConvertResult Double
safeConvert = POSIXTime -> ConvertResult Double
forall a b. Convertible a b => a -> ConvertResult b
safeConvert (POSIXTime -> ConvertResult Double)
-> (UTCTime -> POSIXTime) -> UTCTime -> ConvertResult Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> POSIXTime
utcTimeToPOSIXSeconds
instance Convertible UTCTime Int where
    safeConvert :: UTCTime -> ConvertResult Int
safeConvert = (UTCTime -> ConvertResult Int) -> UTCTime -> ConvertResult Int
forall b a.
(Bounded b, Show a, Show b, Convertible a Integer,
 Convertible b Integer, Typeable a, Typeable b) =>
(a -> ConvertResult b) -> a -> ConvertResult b
boundedConversion (POSIXTime -> ConvertResult Int
forall a b. Convertible a b => a -> ConvertResult b
safeConvert (POSIXTime -> ConvertResult Int)
-> (UTCTime -> POSIXTime) -> UTCTime -> ConvertResult Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> POSIXTime
utcTimeToPOSIXSeconds)

------------------------------ LocalTime stuff

instance Convertible UTCTime ZonedTime where
    safeConvert :: UTCTime -> ConvertResult ZonedTime
safeConvert = ZonedTime -> ConvertResult ZonedTime
forall (m :: * -> *) a. Monad m => a -> m a
return (ZonedTime -> ConvertResult ZonedTime)
-> (UTCTime -> ZonedTime) -> UTCTime -> ConvertResult ZonedTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeZone -> UTCTime -> ZonedTime
utcToZonedTime TimeZone
utc
instance Convertible POSIXTime ZonedTime where
    safeConvert :: POSIXTime -> ConvertResult ZonedTime
safeConvert = ZonedTime -> ConvertResult ZonedTime
forall (m :: * -> *) a. Monad m => a -> m a
return (ZonedTime -> ConvertResult ZonedTime)
-> (POSIXTime -> ZonedTime) -> POSIXTime -> ConvertResult ZonedTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeZone -> UTCTime -> ZonedTime
utcToZonedTime TimeZone
utc (UTCTime -> ZonedTime)
-> (POSIXTime -> UTCTime) -> POSIXTime -> ZonedTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> UTCTime
posixSecondsToUTCTime
instance Convertible ZonedTime UTCTime where
    safeConvert :: ZonedTime -> ConvertResult UTCTime
safeConvert = UTCTime -> ConvertResult UTCTime
forall (m :: * -> *) a. Monad m => a -> m a
return (UTCTime -> ConvertResult UTCTime)
-> (ZonedTime -> UTCTime) -> ZonedTime -> ConvertResult UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> UTCTime
zonedTimeToUTC
instance Convertible ZonedTime POSIXTime where
    safeConvert :: ZonedTime -> ConvertResult POSIXTime
safeConvert = POSIXTime -> ConvertResult POSIXTime
forall (m :: * -> *) a. Monad m => a -> m a
return (POSIXTime -> ConvertResult POSIXTime)
-> (ZonedTime -> POSIXTime) -> ZonedTime -> ConvertResult POSIXTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> POSIXTime
utcTimeToPOSIXSeconds (UTCTime -> POSIXTime)
-> (ZonedTime -> UTCTime) -> ZonedTime -> POSIXTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> UTCTime
zonedTimeToUTC

{- Too obvious?
instance Convertible LocalTime Day where
    safeConvert = return . localDay
instance Convertible LocalTime TimeOfDay where
    safeConvert = return . localTimeOfDay
-}

----------------------------------------------------------------------
-- Conversions between old and new time
----------------------------------------------------------------------
instance Convertible ST.CalendarTime ZonedTime where
    safeConvert :: CalendarTime -> ConvertResult ZonedTime
safeConvert CalendarTime
ct = ZonedTime -> ConvertResult ZonedTime
forall (m :: * -> *) a. Monad m => a -> m a
return (ZonedTime -> ConvertResult ZonedTime)
-> ZonedTime -> ConvertResult ZonedTime
forall a b. (a -> b) -> a -> b
$ ZonedTime :: LocalTime -> TimeZone -> ZonedTime
ZonedTime {
     zonedTimeToLocalTime :: LocalTime
zonedTimeToLocalTime = LocalTime :: Day -> TimeOfDay -> LocalTime
LocalTime {
       localDay :: Day
localDay = Integer -> Int -> Int -> Day
fromGregorian (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ CalendarTime -> Int
ST.ctYear CalendarTime
ct)
                  (Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Month -> Int
forall a. Enum a => a -> Int
fromEnum (CalendarTime -> Month
ST.ctMonth CalendarTime
ct))
                  (CalendarTime -> Int
ST.ctDay CalendarTime
ct),
       localTimeOfDay :: TimeOfDay
localTimeOfDay = TimeOfDay :: Int -> Int -> Pico -> TimeOfDay
TimeOfDay {
         todHour :: Int
todHour = CalendarTime -> Int
ST.ctHour CalendarTime
ct,
         todMin :: Int
todMin = CalendarTime -> Int
ST.ctMin CalendarTime
ct,
         todSec :: Pico
todSec = Int -> Pico
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CalendarTime -> Int
ST.ctSec CalendarTime
ct) Pico -> Pico -> Pico
forall a. Num a => a -> a -> a
+
                  Rational -> Pico
forall a. Fractional a => Rational -> a
fromRational (CalendarTime -> Integer
ST.ctPicosec CalendarTime
ct Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
1000000000000)
                        }
                            },
     zonedTimeZone :: TimeZone
zonedTimeZone = TimeZone :: Int -> Bool -> String -> TimeZone
TimeZone {
                       timeZoneMinutes :: Int
timeZoneMinutes = CalendarTime -> Int
ST.ctTZ CalendarTime
ct Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
60,
                       timeZoneSummerOnly :: Bool
timeZoneSummerOnly = CalendarTime -> Bool
ST.ctIsDST CalendarTime
ct,
                       timeZoneName :: String
timeZoneName = CalendarTime -> String
ST.ctTZName CalendarTime
ct}
}

instance Convertible ST.CalendarTime POSIXTime where
    safeConvert :: CalendarTime -> ConvertResult POSIXTime
safeConvert = ClockTime -> CalendarTime -> ConvertResult POSIXTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (ClockTime
forall a. HasCallStack => a
undefined::ST.ClockTime)
instance Convertible ST.CalendarTime UTCTime where
    safeConvert :: CalendarTime -> ConvertResult UTCTime
safeConvert = POSIXTime -> CalendarTime -> ConvertResult UTCTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined::POSIXTime)

instance Convertible ST.ClockTime POSIXTime where
    safeConvert :: ClockTime -> ConvertResult POSIXTime
safeConvert (ST.TOD Integer
x Integer
y) = POSIXTime -> ConvertResult POSIXTime
forall (m :: * -> *) a. Monad m => a -> m a
return (POSIXTime -> ConvertResult POSIXTime)
-> POSIXTime -> ConvertResult POSIXTime
forall a b. (a -> b) -> a -> b
$ Rational -> POSIXTime
forall a. Fractional a => Rational -> a
fromRational (Rational -> POSIXTime) -> Rational -> POSIXTime
forall a b. (a -> b) -> a -> b
$
                                        Integer -> Rational
forall a. Num a => Integer -> a
fromInteger Integer
x Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ Rational -> Rational
forall a. Fractional a => Rational -> a
fromRational (Integer
y Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
1000000000000)
instance Convertible ST.ClockTime UTCTime where
    safeConvert :: ClockTime -> ConvertResult UTCTime
safeConvert = POSIXTime -> ClockTime -> ConvertResult UTCTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined::POSIXTime)
instance Convertible ST.ClockTime ZonedTime where
    safeConvert :: ClockTime -> ConvertResult ZonedTime
safeConvert = UTCTime -> ClockTime -> ConvertResult ZonedTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (UTCTime
forall a. HasCallStack => a
undefined::UTCTime)
instance Convertible ZonedTime ST.ClockTime where
    safeConvert :: ZonedTime -> ConvertResult ClockTime
safeConvert = POSIXTime -> ZonedTime -> ConvertResult ClockTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined::POSIXTime)

instance Convertible POSIXTime ST.ClockTime where
    safeConvert :: POSIXTime -> ConvertResult ClockTime
safeConvert POSIXTime
x = ClockTime -> ConvertResult ClockTime
forall (m :: * -> *) a. Monad m => a -> m a
return (ClockTime -> ConvertResult ClockTime)
-> ClockTime -> ConvertResult ClockTime
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> ClockTime
ST.TOD Integer
rsecs Integer
rpico
        where rsecs :: Integer
rsecs = POSIXTime -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor POSIXTime
x
              rpico :: Integer
rpico = POSIXTime -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate (POSIXTime -> Integer) -> POSIXTime -> Integer
forall a b. (a -> b) -> a -> b
$ POSIXTime -> POSIXTime
forall a. Num a => a -> a
abs (POSIXTime -> POSIXTime) -> POSIXTime -> POSIXTime
forall a b. (a -> b) -> a -> b
$ POSIXTime
1000000000000 POSIXTime -> POSIXTime -> POSIXTime
forall a. Num a => a -> a -> a
* (POSIXTime
x POSIXTime -> POSIXTime -> POSIXTime
forall a. Num a => a -> a -> a
- Integer -> POSIXTime
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
rsecs)
instance Convertible UTCTime ST.ClockTime where
    safeConvert :: UTCTime -> ConvertResult ClockTime
safeConvert = POSIXTime -> ConvertResult ClockTime
forall a b. Convertible a b => a -> ConvertResult b
safeConvert (POSIXTime -> ConvertResult ClockTime)
-> (UTCTime -> POSIXTime) -> UTCTime -> ConvertResult ClockTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> POSIXTime
utcTimeToPOSIXSeconds

instance Convertible ZonedTime ST.CalendarTime where
    safeConvert :: ZonedTime -> ConvertResult CalendarTime
safeConvert ZonedTime
zt = CalendarTime -> ConvertResult CalendarTime
forall (m :: * -> *) a. Monad m => a -> m a
return (CalendarTime -> ConvertResult CalendarTime)
-> CalendarTime -> ConvertResult CalendarTime
forall a b. (a -> b) -> a -> b
$ CalendarTime :: Int
-> Month
-> Int
-> Int
-> Int
-> Int
-> Integer
-> Day
-> Int
-> String
-> Int
-> Bool
-> CalendarTime
ST.CalendarTime {
            ctYear :: Int
ST.ctYear = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
year,
            ctMonth :: Month
ST.ctMonth = Int -> Month
forall a. Enum a => Int -> a
toEnum (Int
month Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1),
            ctDay :: Int
ST.ctDay = Int
day,
            ctHour :: Int
ST.ctHour = TimeOfDay -> Int
todHour TimeOfDay
ltod,
            ctMin :: Int
ST.ctMin = TimeOfDay -> Int
todMin TimeOfDay
ltod,
            ctSec :: Int
ST.ctSec = Int
secs,
            ctPicosec :: Integer
ST.ctPicosec = Integer
pico,
            ctWDay :: Day
ST.ctWDay = Int -> Day
forall a. Enum a => Int -> a
toEnum (Int -> Day) -> (ZonedTime -> Int) -> ZonedTime -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Int) -> Int
forall a b. (a, b) -> b
snd ((Int, Int) -> Int)
-> (ZonedTime -> (Int, Int)) -> ZonedTime -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> (Int, Int)
sundayStartWeek (Day -> (Int, Int))
-> (ZonedTime -> Day) -> ZonedTime -> (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LocalTime -> Day
localDay (LocalTime -> Day) -> (ZonedTime -> LocalTime) -> ZonedTime -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> LocalTime
zonedTimeToLocalTime (ZonedTime -> Day) -> ZonedTime -> Day
forall a b. (a -> b) -> a -> b
$ ZonedTime
zt,
            ctYDay :: Int
ST.ctYDay = ((Integer, Int) -> Int
forall a b. (a, b) -> b
snd ((Integer, Int) -> Int)
-> (ZonedTime -> (Integer, Int)) -> ZonedTime -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> (Integer, Int)
toOrdinalDate (Day -> (Integer, Int))
-> (ZonedTime -> Day) -> ZonedTime -> (Integer, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LocalTime -> Day
localDay (LocalTime -> Day) -> (ZonedTime -> LocalTime) -> ZonedTime -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> LocalTime
zonedTimeToLocalTime (ZonedTime -> Int) -> ZonedTime -> Int
forall a b. (a -> b) -> a -> b
$ ZonedTime
zt) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,
            ctTZName :: String
ST.ctTZName = TimeZone -> String
timeZoneName (TimeZone -> String)
-> (ZonedTime -> TimeZone) -> ZonedTime -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> TimeZone
zonedTimeZone (ZonedTime -> String) -> ZonedTime -> String
forall a b. (a -> b) -> a -> b
$ ZonedTime
zt,
            ctTZ :: Int
ST.ctTZ = (TimeZone -> Int
timeZoneMinutes (TimeZone -> Int) -> (ZonedTime -> TimeZone) -> ZonedTime -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> TimeZone
zonedTimeZone (ZonedTime -> Int) -> ZonedTime -> Int
forall a b. (a -> b) -> a -> b
$ ZonedTime
zt) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
60,
            ctIsDST :: Bool
ST.ctIsDST = TimeZone -> Bool
timeZoneSummerOnly (TimeZone -> Bool) -> (ZonedTime -> TimeZone) -> ZonedTime -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> TimeZone
zonedTimeZone (ZonedTime -> Bool) -> ZonedTime -> Bool
forall a b. (a -> b) -> a -> b
$ ZonedTime
zt
          }
        where (Integer
year, Int
month, Int
day) = Day -> (Integer, Int, Int)
toGregorian (Day -> (Integer, Int, Int))
-> (ZonedTime -> Day) -> ZonedTime -> (Integer, Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LocalTime -> Day
localDay (LocalTime -> Day) -> (ZonedTime -> LocalTime) -> ZonedTime -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> LocalTime
zonedTimeToLocalTime (ZonedTime -> (Integer, Int, Int))
-> ZonedTime -> (Integer, Int, Int)
forall a b. (a -> b) -> a -> b
$ ZonedTime
zt
              ltod :: TimeOfDay
ltod = LocalTime -> TimeOfDay
localTimeOfDay (LocalTime -> TimeOfDay)
-> (ZonedTime -> LocalTime) -> ZonedTime -> TimeOfDay
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZonedTime -> LocalTime
zonedTimeToLocalTime (ZonedTime -> TimeOfDay) -> ZonedTime -> TimeOfDay
forall a b. (a -> b) -> a -> b
$ ZonedTime
zt
              secs :: Int
secs = (Pico -> Int
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Pico -> Int) -> (TimeOfDay -> Pico) -> TimeOfDay -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeOfDay -> Pico
todSec (TimeOfDay -> Int) -> TimeOfDay -> Int
forall a b. (a -> b) -> a -> b
$ TimeOfDay
ltod)::Int
              picoRational :: Rational
picoRational = Pico -> Rational
forall a. Real a => a -> Rational
toRational (TimeOfDay -> Pico
todSec TimeOfDay
ltod) Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Int -> Rational
forall a. Real a => a -> Rational
toRational Int
secs
              pico :: Integer
pico = Rational -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Rational
picoRational Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
1000000000000)
instance Convertible POSIXTime ST.CalendarTime where
    safeConvert :: POSIXTime -> ConvertResult CalendarTime
safeConvert = ZonedTime -> POSIXTime -> ConvertResult CalendarTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (ZonedTime
forall a. HasCallStack => a
undefined::ZonedTime)
instance Convertible UTCTime ST.CalendarTime where
    safeConvert :: UTCTime -> ConvertResult CalendarTime
safeConvert = POSIXTime -> ConvertResult CalendarTime
forall a b. Convertible a b => a -> ConvertResult b
safeConvert (POSIXTime -> ConvertResult CalendarTime)
-> (UTCTime -> POSIXTime) -> UTCTime -> ConvertResult CalendarTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> POSIXTime
utcTimeToPOSIXSeconds

instance Convertible ST.TimeDiff NominalDiffTime where
    {- This is a clever hack.  We convert the TimeDiff to a ClockTime, applying
       it as a diff vs. the epoch.  Converting this ClockTime to a POSIXTime yiels
       the NominalDiffTime we want, since a POSIXTime is a NominalDiffTime vs. the
       epoch. -}
    safeConvert :: TimeDiff -> ConvertResult POSIXTime
safeConvert TimeDiff
td = ClockTime -> ConvertResult POSIXTime
forall a b. Convertible a b => a -> ConvertResult b
safeConvert ClockTime
clockTime
        where clockTime :: ClockTime
clockTime = TimeDiff -> ClockTime -> ClockTime
ST.addToClockTime TimeDiff
td (Integer -> Integer -> ClockTime
ST.TOD Integer
0 Integer
0)
instance Convertible NominalDiffTime ST.TimeDiff where
    {- Similar clever hack as above. -}
    safeConvert :: POSIXTime -> ConvertResult TimeDiff
safeConvert POSIXTime
ndt =
        do ClockTime
clockt <- POSIXTime -> ConvertResult ClockTime
forall a b. Convertible a b => a -> ConvertResult b
safeConvert POSIXTime
ndt
           TimeDiff -> ConvertResult TimeDiff
forall (m :: * -> *) a. Monad m => a -> m a
return (ClockTime -> ClockTime -> TimeDiff
ST.diffClockTimes ClockTime
clockt (Integer -> Integer -> ClockTime
ST.TOD Integer
0 Integer
0))

instance Convertible Integer ST.TimeDiff where
    safeConvert :: Integer -> ConvertResult TimeDiff
safeConvert = POSIXTime -> Integer -> ConvertResult TimeDiff
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined::NominalDiffTime)
instance Convertible Double ST.TimeDiff where
    safeConvert :: Double -> ConvertResult TimeDiff
safeConvert = POSIXTime -> Double -> ConvertResult TimeDiff
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined::NominalDiffTime)
instance Convertible ST.TimeDiff Integer where
    safeConvert :: TimeDiff -> ConvertResult Integer
safeConvert = POSIXTime -> TimeDiff -> ConvertResult Integer
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined :: NominalDiffTime)
instance Convertible ST.TimeDiff Rational where
    safeConvert :: TimeDiff -> ConvertResult Rational
safeConvert = POSIXTime -> TimeDiff -> ConvertResult Rational
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined :: NominalDiffTime)
instance Convertible ST.TimeDiff Double where
    safeConvert :: TimeDiff -> ConvertResult Double
safeConvert = POSIXTime -> TimeDiff -> ConvertResult Double
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined :: NominalDiffTime)

----------------------------------------------------------------------
-- Foreign.C Types
----------------------------------------------------------------------

instance Convertible CTime POSIXTime where
    safeConvert :: CTime -> ConvertResult POSIXTime
safeConvert = POSIXTime -> ConvertResult POSIXTime
forall (m :: * -> *) a. Monad m => a -> m a
return (POSIXTime -> ConvertResult POSIXTime)
-> (CTime -> POSIXTime) -> CTime -> ConvertResult POSIXTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CTime -> POSIXTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac
instance Convertible POSIXTime CTime where
    safeConvert :: POSIXTime -> ConvertResult CTime
safeConvert = CTime -> ConvertResult CTime
forall (m :: * -> *) a. Monad m => a -> m a
return (CTime -> ConvertResult CTime)
-> (POSIXTime -> CTime) -> POSIXTime -> ConvertResult CTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> CTime
forall a. Num a => Integer -> a
fromInteger (Integer -> CTime) -> (POSIXTime -> Integer) -> POSIXTime -> CTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate

instance Convertible CTime Integer where
    safeConvert :: CTime -> ConvertResult Integer
safeConvert = Integer -> ConvertResult Integer
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> ConvertResult Integer)
-> (CTime -> Integer) -> CTime -> ConvertResult Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Rational -> Integer) -> (CTime -> Rational) -> CTime -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CTime -> Rational
forall a. Real a => a -> Rational
toRational
instance Convertible Integer CTime where
    safeConvert :: Integer -> ConvertResult CTime
safeConvert = CTime -> ConvertResult CTime
forall (m :: * -> *) a. Monad m => a -> m a
return (CTime -> ConvertResult CTime)
-> (Integer -> CTime) -> Integer -> ConvertResult CTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> CTime
forall a. Num a => Integer -> a
fromInteger

instance Convertible CTime Double where
    safeConvert :: CTime -> ConvertResult Double
safeConvert = Double -> ConvertResult Double
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> ConvertResult Double)
-> (CTime -> Double) -> CTime -> ConvertResult Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CTime -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac
instance Convertible Double CTime where
    safeConvert :: Double -> ConvertResult CTime
safeConvert = CTime -> ConvertResult CTime
forall (m :: * -> *) a. Monad m => a -> m a
return (CTime -> ConvertResult CTime)
-> (Double -> CTime) -> Double -> ConvertResult CTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> CTime
forall a. Num a => Integer -> a
fromInteger (Integer -> CTime) -> (Double -> Integer) -> Double -> CTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate

instance Convertible CTime Int where
    safeConvert :: CTime -> ConvertResult Int
safeConvert CTime
x = do Integer
r1 <- CTime -> ConvertResult Integer
forall a b. Convertible a b => a -> ConvertResult b
safeConvert CTime
x
                       (Integer -> ConvertResult Int) -> Integer -> ConvertResult Int
forall b a.
(Bounded b, Show a, Show b, Convertible a Integer,
 Convertible b Integer, Typeable a, Typeable b) =>
(a -> ConvertResult b) -> a -> ConvertResult b
boundedConversion (Int -> ConvertResult Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> ConvertResult Int)
-> (Integer -> Int) -> Integer -> ConvertResult Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Int
forall a. Num a => Integer -> a
fromInteger) Integer
r1
instance Convertible Int CTime where
    safeConvert :: Int -> ConvertResult CTime
safeConvert = Integer -> ConvertResult CTime
forall a b. Convertible a b => a -> ConvertResult b
safeConvert (Integer -> ConvertResult CTime)
-> (Int -> Integer) -> Int -> ConvertResult CTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a. Integral a => a -> Integer
toInteger

instance Convertible CTime UTCTime where
    safeConvert :: CTime -> ConvertResult UTCTime
safeConvert = POSIXTime -> CTime -> ConvertResult UTCTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined :: POSIXTime)
instance Convertible UTCTime CTime where
    safeConvert :: UTCTime -> ConvertResult CTime
safeConvert = POSIXTime -> UTCTime -> ConvertResult CTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined :: POSIXTime)

instance Convertible CTime ST.ClockTime where
    safeConvert :: CTime -> ConvertResult ClockTime
safeConvert = POSIXTime -> CTime -> ConvertResult ClockTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined :: POSIXTime)
instance Convertible ST.ClockTime CTime where
    safeConvert :: ClockTime -> ConvertResult CTime
safeConvert = POSIXTime -> ClockTime -> ConvertResult CTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined :: POSIXTime)

instance Convertible CTime ST.CalendarTime where
    safeConvert :: CTime -> ConvertResult CalendarTime
safeConvert = POSIXTime -> CTime -> ConvertResult CalendarTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined::POSIXTime)
instance Convertible ST.CalendarTime CTime where
    safeConvert :: CalendarTime -> ConvertResult CTime
safeConvert = POSIXTime -> CalendarTime -> ConvertResult CTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined::POSIXTime)

instance Convertible CTime ZonedTime where
    safeConvert :: CTime -> ConvertResult ZonedTime
safeConvert = POSIXTime -> CTime -> ConvertResult ZonedTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined::POSIXTime)
instance Convertible ZonedTime CTime where
    safeConvert :: ZonedTime -> ConvertResult CTime
safeConvert = POSIXTime -> ZonedTime -> ConvertResult CTime
forall a b c.
(Convertible a b, Convertible b c) =>
b -> a -> ConvertResult c
convertVia (POSIXTime
forall a. HasCallStack => a
undefined::POSIXTime)