    {- |
       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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 b. Integral b => POSIXTime -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate
    instance Convertible POSIXTime Rational where
        safeConvert :: POSIXTime -> ConvertResult Rational
    safeConvert = Rational -> ConvertResult Rational
    forall a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 b. Integral b => POSIXTime -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate)

    instance Convertible POSIXTime UTCTime where
        safeConvert :: POSIXTime -> ConvertResult UTCTime
    safeConvert = UTCTime -> ConvertResult UTCTime
    forall a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ZonedTime -> ConvertResult ZonedTime)
    -> ZonedTime -> ConvertResult ZonedTime
    forall a b. (a -> b) -> a -> b
    $ ZonedTime {
         zonedTimeToLocalTime :: LocalTime
    zonedTimeToLocalTime = 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 {
             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 {
                           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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 b. Integral b => POSIXTime -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor POSIXTime
    x
                  rpico :: Integer
    rpico = POSIXTime -> Integer
    forall b. Integral b => POSIXTime -> b
    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 a. a -> Either ConvertError a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CalendarTime -> ConvertResult CalendarTime)
    -> CalendarTime -> ConvertResult CalendarTime
    forall a b. (a -> b) -> a -> b
    $ 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 b. Integral b => Pico -> b
    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 b. Integral b => Rational -> b
    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 clockt <- POSIXTime -> ConvertResult ClockTime
    forall a b. Convertible a b => a -> ConvertResult b
    safeConvert POSIXTime
    ndt
               return (ST.diffClockTimes clockt (ST.TOD 0 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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 b. Integral b => POSIXTime -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate

    instance Convertible CTime Integer where
        safeConvert :: CTime -> ConvertResult Integer
    safeConvert = Integer -> ConvertResult Integer
    forall a. a -> Either ConvertError a
    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 b. Integral b => Rational -> b
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 a. a -> Either ConvertError a
    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 b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate

    instance Convertible CTime Int where
        safeConvert :: CTime -> ConvertResult Int
    safeConvert CTime
    x = do r1 <- CTime -> ConvertResult Integer
    forall a b. Convertible a b => a -> ConvertResult b
    safeConvert CTime
    x
                           boundedConversion (return . fromInteger) 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)