    {-# LANGUAGE Safe #-}

    {-# OPTIONS -fno-warn-orphans #-}

    module Data.Time.LocalTime.Internal.ZonedTime (
        ZonedTime (..),
        utcToZonedTime,
        zonedTimeToUTC,
        getZonedTime,
        utcToLocalZonedTime,
    ) where

    import Control.DeepSeq
    import Data.Data
    import Data.Time.Clock.Internal.UTCTime
    import Data.Time.Clock.POSIX
    import Data.Time.LocalTime.Internal.LocalTime
    import Data.Time.LocalTime.Internal.TimeZone

    -- | A local time together with a time zone.
    --
    -- There is no 'Eq' instance for @ZonedTime@.
    -- If you want to compare local times, use 'zonedTimeToLocalTime'.
    -- If you want to compare absolute times, use 'zonedTimeToUTC'.
    data ZonedTime = ZonedTime
        { ZonedTime -> LocalTime
    zonedTimeToLocalTime :: LocalTime
        , ZonedTime -> TimeZone
    zonedTimeZone :: TimeZone
        }
        deriving (Typeable ZonedTime
    Typeable ZonedTime =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> ZonedTime -> c ZonedTime)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c ZonedTime)
    -> (ZonedTime -> Constr)
    -> (ZonedTime -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c ZonedTime))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ZonedTime))
    -> ((forall b. Data b => b -> b) -> ZonedTime -> ZonedTime)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> ZonedTime -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> ZonedTime -> r)
    -> (forall u. (forall d. Data d => d -> u) -> ZonedTime -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> ZonedTime -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime)
    -> Data ZonedTime
    ZonedTime -> Constr
    ZonedTime -> DataType
    (forall b. Data b => b -> b) -> ZonedTime -> ZonedTime
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> ZonedTime -> u
    forall u. (forall d. Data d => d -> u) -> ZonedTime -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ZonedTime -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ZonedTime -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ZonedTime
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ZonedTime -> c ZonedTime
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ZonedTime)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ZonedTime)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ZonedTime -> c ZonedTime
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ZonedTime -> c ZonedTime
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ZonedTime
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ZonedTime
    $ctoConstr :: ZonedTime -> Constr
    toConstr :: ZonedTime -> Constr
    $cdataTypeOf :: ZonedTime -> DataType
    dataTypeOf :: ZonedTime -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ZonedTime)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ZonedTime)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ZonedTime)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ZonedTime)
    $cgmapT :: (forall b. Data b => b -> b) -> ZonedTime -> ZonedTime
    gmapT :: (forall b. Data b => b -> b) -> ZonedTime -> ZonedTime
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ZonedTime -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ZonedTime -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ZonedTime -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ZonedTime -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> ZonedTime -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> ZonedTime -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ZonedTime -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ZonedTime -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ZonedTime -> m ZonedTime
    Data, Typeable)

    instance NFData ZonedTime where
        rnf :: ZonedTime -> ()
    rnf (ZonedTime LocalTime
    lt TimeZone
    z) = LocalTime -> ()
    forall a. NFData a => a -> ()
    rnf LocalTime
    lt () -> () -> ()
    forall a b. a -> b -> b
    `seq` TimeZone -> ()
    forall a. NFData a => a -> ()
    rnf TimeZone
    z () -> () -> ()
    forall a b. a -> b -> b
    `seq` ()

    utcToZonedTime :: TimeZone -> UTCTime -> ZonedTime
    utcToZonedTime :: TimeZone -> UTCTime -> ZonedTime
    utcToZonedTime TimeZone
    zone UTCTime
    time = LocalTime -> TimeZone -> ZonedTime
    ZonedTime (TimeZone -> UTCTime -> LocalTime
    utcToLocalTime TimeZone
    zone UTCTime
    time) TimeZone
    zone

    zonedTimeToUTC :: ZonedTime -> UTCTime
    zonedTimeToUTC :: ZonedTime -> UTCTime
    zonedTimeToUTC (ZonedTime LocalTime
    t TimeZone
    zone) = TimeZone -> LocalTime -> UTCTime
    localTimeToUTC TimeZone
    zone LocalTime
    t

    -- | For the time zone, this only shows the name, or offset if the name is empty.
    instance Show ZonedTime where
        show :: ZonedTime -> String
    show (ZonedTime LocalTime
    t TimeZone
    zone) = LocalTime -> String
    forall a. Show a => a -> String
    show LocalTime
    t String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ TimeZone -> String
    forall a. Show a => a -> String
    show TimeZone
    zone

    -- orphan instance
    instance Show UTCTime where
        show :: UTCTime -> String
    show UTCTime
    t = ZonedTime -> String
    forall a. Show a => a -> String
    show (TimeZone -> UTCTime -> ZonedTime
    utcToZonedTime TimeZone
    utc UTCTime
    t)

    getZonedTime :: IO ZonedTime
    getZonedTime :: IO ZonedTime
    getZonedTime = do
        t <- IO UTCTime
    getCurrentTime
        zone <- getTimeZone t
        return (utcToZonedTime zone t)

    utcToLocalZonedTime :: UTCTime -> IO ZonedTime
    utcToLocalZonedTime :: UTCTime -> IO ZonedTime
    utcToLocalZonedTime UTCTime
    t = do
        zone <- UTCTime -> IO TimeZone
    getTimeZone UTCTime
    t
        return (utcToZonedTime zone t)