    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE RecordWildCards #-}
    {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE ViewPatterns #-}
    {-# OPTIONS_GHC -fno-warn-orphans #-}

    #include "thyme.h"

    module Data.Thyme.LocalTime where

    import Prelude hiding ((.))
    import Control.Applicative
    import Control.Arrow
    import Control.Category hiding (id)
    import Control.DeepSeq
    import Control.Lens
    import Control.Monad
    import Data.AffineSpace
    import Data.Bits
    import Data.Data
    import Data.Int
    import Data.Thyme.Internal.Micro
    import Data.Thyme.Calendar
    import Data.Thyme.Calendar.Internal
    import Data.Thyme.Clock
    import Data.Thyme.Clock.Internal
    import Data.Thyme.Format.Internal
    import qualified Data.Time as T
    #if __GLASGOW_HASKELL__ == 704
    import qualified Data.Vector.Generic
    import qualified Data.Vector.Generic.Mutable
    #endif
    import Data.Vector.Unboxed.Deriving
    import Data.VectorSpace
    import GHC.Generics (Generic)
    import System.Random
    import Test.QuickCheck hiding ((.&.))

    type Minutes = Int
    type Hours = Int

    ------------------------------------------------------------------------
    -- * Time zones

    data TimeZone = TimeZone
        { TimeZone -> Minutes
    timeZoneMinutes :: {-# UNPACK #-}!Minutes
        , TimeZone -> Bool
    timeZoneSummerOnly :: !Bool
        , TimeZone -> String
    timeZoneName :: String
        } deriving (INSTANCES_USUAL)

    instance NFData TimeZone

    #if SHOW_INTERNAL
    deriving instance Show TimeZone
    #else
    instance Show TimeZone where
        show :: TimeZone -> String
    show tz :: TimeZone
    tz@TimeZone {..} = if String -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    timeZoneName
            then TimeZone -> String
    timeZoneOffsetString TimeZone
    tz else String
    timeZoneName
    #endif

    instance Bounded TimeZone where
        minBound :: TimeZone
    minBound = Minutes -> Bool -> String -> TimeZone
    TimeZone (-12 Minutes -> Minutes -> Minutes
    forall a. Num a => a -> a -> a
    * 60) Bool
    forall a. Bounded a => a
    minBound "AAAA"
        maxBound :: TimeZone
    maxBound = Minutes -> Bool -> String -> TimeZone
    TimeZone (13 Minutes -> Minutes -> Minutes
    forall a. Num a => a -> a -> a
    * 60) Bool
    forall a. Bounded a => a
    maxBound "ZZZZ"

    instance Random TimeZone where
        randomR :: (TimeZone, TimeZone) -> g -> (TimeZone, g)
    randomR (l :: TimeZone
    l, u :: TimeZone
    u) g0 :: g
    g0 = (Minutes -> Bool -> String -> TimeZone
    TimeZone Minutes
    minutes Bool
    summer String
    name, g
    g3) where
            (minutes :: Minutes
    minutes, g1 :: g
    g1) = (Minutes, Minutes) -> g -> (Minutes, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (TimeZone -> Minutes
    timeZoneMinutes TimeZone
    l, TimeZone -> Minutes
    timeZoneMinutes TimeZone
    u) g
    g0
            (summer :: Bool
    summer, g2 :: g
    g2) = (Bool, Bool) -> g -> (Bool, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (TimeZone -> Bool
    timeZoneSummerOnly TimeZone
    l, TimeZone -> Bool
    timeZoneSummerOnly TimeZone
    u) g
    g1
            -- slightly dubious interpretation of ‘range’
            (name :: String
    name, g3 :: g
    g3) = ((Char, Char) -> (String, g) -> (String, g))
    -> (String, g) -> [(Char, Char)] -> (String, g)
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (Char, Char) -> (String, g) -> (String, g)
    forall a g.
    (Random a, RandomGen g) =>
    (a, a) -> ([a], g) -> ([a], g)
    randChar ([], g
    g2) ([(Char, Char)] -> (String, g))
    -> ([(Char, Char)] -> [(Char, Char)])
    -> [(Char, Char)]
    -> (String, g)
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Minutes -> [(Char, Char)] -> [(Char, Char)]
    forall a. Minutes -> [a] -> [a]
    take 4 ([(Char, Char)] -> (String, g)) -> [(Char, Char)] -> (String, g)
    forall a b. (a -> b) -> a -> b
    $ String -> String -> [(Char, Char)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip
                (TimeZone -> String
    timeZoneName TimeZone
    l String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ "AAAA") (TimeZone -> String
    timeZoneName TimeZone
    u String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ "ZZZZ")
            randChar :: (a, a) -> ([a], g) -> ([a], g)
    randChar nR :: (a, a)
    nR (ns :: [a]
    ns, g :: g
    g) = (a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : [a]
    ns) (a -> [a]) -> (a, g) -> ([a], g)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    `first` (a, a) -> g -> (a, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (a, a)
    nR g
    g
        random :: g -> (TimeZone, g)
    random = (TimeZone, TimeZone) -> g -> (TimeZone, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (TimeZone
    forall a. Bounded a => a
    minBound, TimeZone
    forall a. Bounded a => a
    maxBound)

    instance Arbitrary TimeZone where
        arbitrary :: Gen TimeZone
    arbitrary = (TimeZone, TimeZone) -> Gen TimeZone
    forall a. Random a => (a, a) -> Gen a
    choose (TimeZone
    forall a. Bounded a => a
    minBound, TimeZone
    forall a. Bounded a => a
    maxBound)
        shrink :: TimeZone -> [TimeZone]
    shrink tz :: TimeZone
    tz@TimeZone {..}
            = [ TimeZone
    tz {timeZoneSummerOnly :: Bool
    timeZoneSummerOnly = Bool
    s} | Bool
    s <- Bool -> [Bool]
    forall a. Arbitrary a => a -> [a]
    shrink Bool
    timeZoneSummerOnly ]
            [TimeZone] -> [TimeZone] -> [TimeZone]
    forall a. [a] -> [a] -> [a]
    ++ [ TimeZone
    tz {timeZoneMinutes :: Minutes
    timeZoneMinutes = Minutes
    m} | Minutes
    m <- Minutes -> [Minutes]
    forall a. Arbitrary a => a -> [a]
    shrink Minutes
    timeZoneMinutes ]
            [TimeZone] -> [TimeZone] -> [TimeZone]
    forall a. [a] -> [a] -> [a]
    ++ [ TimeZone
    tz {timeZoneName :: String
    timeZoneName = String
    n} | String
    n <- String -> [String]
    forall a. Arbitrary a => a -> [a]
    shrink String
    timeZoneName ]

    instance CoArbitrary TimeZone where
        coarbitrary :: TimeZone -> Gen b -> Gen b
    coarbitrary (TimeZone m :: Minutes
    m s :: Bool
    s n :: String
    n)
            = Minutes -> Gen b -> Gen b
    forall a b. CoArbitrary a => a -> Gen b -> Gen b
    coarbitrary Minutes
    m (Gen b -> Gen b) -> (Gen b -> Gen b) -> Gen b -> Gen b
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Bool -> Gen b -> Gen b
    forall a b. CoArbitrary a => a -> Gen b -> Gen b
    coarbitrary Bool
    s (Gen b -> Gen b) -> (Gen b -> Gen b) -> Gen b -> Gen b
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . String -> Gen b -> Gen b
    forall a b. CoArbitrary a => a -> Gen b -> Gen b
    coarbitrary String
    n

    -- | Text representing the offset of this timezone, e.g. \"-0800\" or
    -- \"+0400\" (like %z in 'formatTime')
    {-# INLINEABLE timeZoneOffsetString #-}
    timeZoneOffsetString :: TimeZone -> String
    timeZoneOffsetString :: TimeZone -> String
    timeZoneOffsetString TimeZone {..} = Char
    sign Char -> ShowS
    forall a. a -> [a] -> [a]
    : (Minutes -> ShowS
    shows02 Minutes
    h ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Minutes -> ShowS
    shows02 Minutes
    m) "" where
        (h :: Minutes
    h, m :: Minutes
    m) = Minutes -> Minutes -> (Minutes, Minutes)
    forall a. Integral a => a -> a -> (a, a)
    divMod Minutes
    offset 60
        (sign :: Char
    sign, offset :: Minutes
    offset) = if Minutes
    timeZoneMinutes Minutes -> Minutes -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0
            then ('-', Minutes -> Minutes
    forall a. Num a => a -> a
    negate Minutes
    timeZoneMinutes) else ('+', Minutes
    timeZoneMinutes)

    -- | Create a nameless non-summer timezone for this number of minutes
    minutesToTimeZone :: Minutes -> TimeZone
    minutesToTimeZone :: Minutes -> TimeZone
    minutesToTimeZone m :: Minutes
    m = Minutes -> Bool -> String -> TimeZone
    TimeZone Minutes
    m Bool
    False ""

    -- | Create a nameless non-summer timezone for this number of hours
    hoursToTimeZone :: Hours -> TimeZone
    hoursToTimeZone :: Minutes -> TimeZone
    hoursToTimeZone i :: Minutes
    i = Minutes -> TimeZone
    minutesToTimeZone (60 Minutes -> Minutes -> Minutes
    forall a. Num a => a -> a -> a
    * Minutes
    i)

    utc :: TimeZone
    utc :: TimeZone
    utc = Minutes -> Bool -> String -> TimeZone
    TimeZone 0 Bool
    False "UTC"

    {-# INLINEABLE getTimeZone #-}
    getTimeZone :: UTCTime -> IO TimeZone
    getTimeZone :: UTCTime -> IO TimeZone
    getTimeZone t :: UTCTime
    t = TimeZone -> TimeZone
    thyme (TimeZone -> TimeZone) -> IO TimeZone -> IO TimeZone
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` UTCTime -> IO TimeZone
    T.getTimeZone (Day -> DiffTime -> UTCTime
    T.UTCTime Day
    day (DiffTime -> UTCTime) -> DiffTime -> UTCTime
    forall a b. (a -> b) -> a -> b
    $ DiffTime -> DiffTime
    forall t n. (TimeDiff t, Fractional n) => t -> n
    toSeconds DiffTime
    dt) where
        day :: Day
    day = Integer -> Day
    T.ModifiedJulianDay (Minutes -> Integer
    forall a. Integral a => a -> Integer
    toInteger Minutes
    mjd)
        UTCTime (ModifiedJulianDay mjd :: Minutes
    mjd) dt :: DiffTime
    dt = UTCTime
    t UTCTime -> Getting UTCView UTCTime UTCView -> UTCView
    forall s a. s -> Getting a s a -> a
    ^. Getting UTCView UTCTime UTCView
    Iso' UTCTime UTCView
    utcTime
        thyme :: TimeZone -> TimeZone
    thyme T.TimeZone {..} = $WTimeZone :: Minutes -> Bool -> String -> TimeZone
    TimeZone {..}

    {-# INLINE getCurrentTimeZone #-}
    getCurrentTimeZone :: IO TimeZone
    getCurrentTimeZone :: IO TimeZone
    getCurrentTimeZone = IO UTCTime
    getCurrentTime IO UTCTime -> (UTCTime -> IO TimeZone) -> IO TimeZone
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= UTCTime -> IO TimeZone
    getTimeZone

    ------------------------------------------------------------------------
    -- * Time of day

    type Hour = Int
    type Minute = Int
    data TimeOfDay = TimeOfDay
        { TimeOfDay -> Minutes
    todHour :: {-# UNPACK #-}!Hour
        , TimeOfDay -> Minutes
    todMin :: {-# UNPACK #-}!Minute
        , TimeOfDay -> DiffTime
    todSec :: {-# UNPACK #-}!DiffTime
        } deriving (INSTANCES_USUAL)

    derivingUnbox "TimeOfDay" [t| TimeOfDay -> Int64 |]
        [| \ TimeOfDay {..} -> fromIntegral (todHour .|. shiftL todMin 8)
            .|. shiftL (todSec ^. microseconds) 16 |]
        [| \ n -> TimeOfDay (fromIntegral $ n .&. 0xff)
            (fromIntegral $ shiftR n 8 .&. 0xff) (microseconds # shiftR n 16) |]

    instance NFData TimeOfDay

    #if SHOW_INTERNAL
    deriving instance Show TimeOfDay
    #else
    instance Show TimeOfDay where
        showsPrec :: Minutes -> TimeOfDay -> ShowS
    showsPrec _ (TimeOfDay h :: Minutes
    h m :: Minutes
    m (DiffTime s :: Micro
    s))
                = Minutes -> ShowS
    shows02 Minutes
    h ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (:) ':' ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Minutes -> ShowS
    shows02 Minutes
    m ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (:) ':'
                ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Minutes -> ShowS
    shows02 (Int64 -> Minutes
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int64
    si) ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . ShowS
    frac where
            (si :: Int64
    si, Micro su :: Int64
    su) = Micro -> Micro -> (Int64, Micro)
    microQuotRem Micro
    s (Int64 -> Micro
    Micro 1000000)
            frac :: ShowS
    frac = if Int64
    su Int64 -> Int64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0 then ShowS
    forall a. a -> a
    id else (:) '.' ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Int64 -> ShowS
    fills06 Int64
    su ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Int64 -> ShowS
    drops0 Int64
    su
    #endif

    instance Bounded TimeOfDay where
        minBound :: TimeOfDay
    minBound = Minutes -> Minutes -> DiffTime -> TimeOfDay
    TimeOfDay 0 0 DiffTime
    forall v. AdditiveGroup v => v
    zeroV
        maxBound :: TimeOfDay
    maxBound = Minutes -> Minutes -> DiffTime -> TimeOfDay
    TimeOfDay 23 59 (Overloaded Reviewed Identity DiffTime DiffTime Int64 Int64
    forall t. TimeDiff t => Iso' t Int64
    microseconds Overloaded Reviewed Identity DiffTime DiffTime Int64 Int64
    -> Int64 -> DiffTime
    forall s t a b. AReview s t a b -> b -> t
    # 60999999)

    instance Random TimeOfDay where
        randomR :: (TimeOfDay, TimeOfDay) -> g -> (TimeOfDay, g)
    randomR = Iso' DiffTime TimeOfDay
    -> (TimeOfDay, TimeOfDay) -> g -> (TimeOfDay, g)
    forall s g a.
    (Random s, RandomGen g) =>
    Iso' s a -> (a, a) -> g -> (a, g)
    randomIsoR Iso' DiffTime TimeOfDay
    timeOfDay
        random :: g -> (TimeOfDay, g)
    random = (DiffTime -> TimeOfDay) -> (DiffTime, g) -> (TimeOfDay, g)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    first (DiffTime -> Getting TimeOfDay DiffTime TimeOfDay -> TimeOfDay
    forall s a. s -> Getting a s a -> a
    ^. Getting TimeOfDay DiffTime TimeOfDay
    Iso' DiffTime TimeOfDay
    timeOfDay) ((DiffTime, g) -> (TimeOfDay, g))
    -> (g -> (DiffTime, g)) -> g -> (TimeOfDay, g)
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . g -> (DiffTime, g)
    forall a g. (Random a, RandomGen g) => g -> (a, g)
    random

    instance Arbitrary TimeOfDay where
        arbitrary :: Gen TimeOfDay
    arbitrary = do
            Minutes
    h <- (Minutes, Minutes) -> Gen Minutes
    forall a. Random a => (a, a) -> Gen a
    choose (0, 23)
            Minutes
    m <- (Minutes, Minutes) -> Gen Minutes
    forall a. Random a => (a, a) -> Gen a
    choose (0, 59)
            let DiffTime ml :: Micro
    ml = Minutes -> Minutes -> DiffTime
    minuteLength Minutes
    h Minutes
    m
            Minutes -> Minutes -> DiffTime -> TimeOfDay
    TimeOfDay Minutes
    h Minutes
    m (DiffTime -> TimeOfDay)
    -> (Micro -> DiffTime) -> Micro -> TimeOfDay
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Micro -> DiffTime
    DiffTime (Micro -> TimeOfDay) -> Gen Micro -> Gen TimeOfDay
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Micro, Micro) -> Gen Micro
    forall a. Random a => (a, a) -> Gen a
    choose (Micro
    forall v. AdditiveGroup v => v
    zeroV, Micro -> Micro
    forall a. Enum a => a -> a
    pred Micro
    ml)
        shrink :: TimeOfDay -> [TimeOfDay]
    shrink tod :: TimeOfDay
    tod = Getting TimeOfDay DiffTime TimeOfDay -> DiffTime -> TimeOfDay
    forall a s. Getting a s a -> s -> a
    view Getting TimeOfDay DiffTime TimeOfDay
    Iso' DiffTime TimeOfDay
    timeOfDay (DiffTime -> TimeOfDay)
    -> (DiffTime -> DiffTime) -> DiffTime -> TimeOfDay
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . DiffTime -> DiffTime -> DiffTime
    forall v. AdditiveGroup v => v -> v -> v
    (^+^) DiffTime
    noon
                (DiffTime -> TimeOfDay) -> [DiffTime] -> [TimeOfDay]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> DiffTime -> [DiffTime]
    forall a. Arbitrary a => a -> [a]
    shrink (Overloaded Reviewed Identity DiffTime DiffTime TimeOfDay TimeOfDay
    Iso' DiffTime TimeOfDay
    timeOfDay Overloaded Reviewed Identity DiffTime DiffTime TimeOfDay TimeOfDay
    -> TimeOfDay -> DiffTime
    forall s t a b. AReview s t a b -> b -> t
    # TimeOfDay
    tod DiffTime -> DiffTime -> DiffTime
    forall v. AdditiveGroup v => v -> v -> v
    ^-^ DiffTime
    noon) where
            noon :: DiffTime
    noon = Overloaded Reviewed Identity DiffTime DiffTime TimeOfDay TimeOfDay
    Iso' DiffTime TimeOfDay
    timeOfDay Overloaded Reviewed Identity DiffTime DiffTime TimeOfDay TimeOfDay
    -> TimeOfDay -> DiffTime
    forall s t a b. AReview s t a b -> b -> t
    # TimeOfDay
    midday -- shrink towards midday

    instance CoArbitrary TimeOfDay where
        coarbitrary :: TimeOfDay -> Gen b -> Gen b
    coarbitrary (TimeOfDay h :: Minutes
    h m :: Minutes
    m s :: DiffTime
    s)
            = Minutes -> Gen b -> Gen b
    forall a b. CoArbitrary a => a -> Gen b -> Gen b
    coarbitrary Minutes
    h (Gen b -> Gen b) -> (Gen b -> Gen b) -> Gen b -> Gen b
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Minutes -> Gen b -> Gen b
    forall a b. CoArbitrary a => a -> Gen b -> Gen b
    coarbitrary Minutes
    m (Gen b -> Gen b) -> (Gen b -> Gen b) -> Gen b -> Gen b
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . DiffTime -> Gen b -> Gen b
    forall a b. CoArbitrary a => a -> Gen b -> Gen b
    coarbitrary DiffTime
    s

    {-# INLINE minuteLength #-}
    minuteLength :: Hour -> Minute -> DiffTime
    minuteLength :: Minutes -> Minutes -> DiffTime
    minuteLength h :: Minutes
    h m :: Minutes
    m = Rational -> DiffTime
    forall t. TimeDiff t => Rational -> t
    fromSeconds' (Rational -> DiffTime) -> Rational -> DiffTime
    forall a b. (a -> b) -> a -> b
    $ if Minutes
    h Minutes -> Minutes -> Bool
    forall a. Eq a => a -> a -> Bool
    == 23 Bool -> Bool -> Bool
    && Minutes
    m Minutes -> Minutes -> Bool
    forall a. Eq a => a -> a -> Bool
    == 59 then 61 else 60

    -- | Hour zero
    midnight :: TimeOfDay
    midnight :: TimeOfDay
    midnight = Minutes -> Minutes -> DiffTime -> TimeOfDay
    TimeOfDay 0 0 DiffTime
    forall v. AdditiveGroup v => v
    zeroV

    -- | Hour twelve
    midday :: TimeOfDay
    midday :: TimeOfDay
    midday = Minutes -> Minutes -> DiffTime -> TimeOfDay
    TimeOfDay 12 0 DiffTime
    forall v. AdditiveGroup v => v
    zeroV

    {-# INLINE makeTimeOfDayValid #-}
    makeTimeOfDayValid :: Hour -> Minute -> DiffTime -> Maybe TimeOfDay
    makeTimeOfDayValid :: Minutes -> Minutes -> DiffTime -> Maybe TimeOfDay
    makeTimeOfDayValid h :: Minutes
    h m :: Minutes
    m s :: DiffTime
    s = Minutes -> Minutes -> DiffTime -> TimeOfDay
    TimeOfDay Minutes
    h Minutes
    m DiffTime
    s
        TimeOfDay -> Maybe () -> Maybe TimeOfDay
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Bool -> Maybe ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (0 Minutes -> Minutes -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Minutes
    h Bool -> Bool -> Bool
    && Minutes
    h Minutes -> Minutes -> Bool
    forall a. Ord a => a -> a -> Bool
    <= 23 Bool -> Bool -> Bool
    && 0 Minutes -> Minutes -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Minutes
    m Bool -> Bool -> Bool
    && Minutes
    m Minutes -> Minutes -> Bool
    forall a. Ord a => a -> a -> Bool
    <= 59)
        Maybe TimeOfDay -> Maybe () -> Maybe TimeOfDay
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* Bool -> Maybe ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (DiffTime
    forall v. AdditiveGroup v => v
    zeroV DiffTime -> DiffTime -> Bool
    forall a. Ord a => a -> a -> Bool
    <= DiffTime
    s Bool -> Bool -> Bool
    && DiffTime
    s DiffTime -> DiffTime -> Bool
    forall a. Ord a => a -> a -> Bool
    < Minutes -> Minutes -> DiffTime
    minuteLength Minutes
    h Minutes
    m)

    {-# INLINE timeOfDay #-}
    timeOfDay :: Iso' DiffTime TimeOfDay
    timeOfDay :: Overloaded p f DiffTime DiffTime TimeOfDay TimeOfDay
    timeOfDay = (DiffTime -> TimeOfDay)
    -> (TimeOfDay -> DiffTime) -> Iso' DiffTime TimeOfDay
    forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
    iso DiffTime -> TimeOfDay
    fromDiff TimeOfDay -> DiffTime
    toDiff where

        {-# INLINEABLE fromDiff #-}
        fromDiff :: DiffTime -> TimeOfDay
        fromDiff :: DiffTime -> TimeOfDay
    fromDiff (DiffTime t :: Micro
    t) = Minutes -> Minutes -> DiffTime -> TimeOfDay
    TimeOfDay
                (Int64 -> Minutes
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int64
    h) (Int64 -> Minutes
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int64
    m) (Micro -> DiffTime
    DiffTime Micro
    s) where
            (h :: Int64
    h, ms :: Micro
    ms) = Micro -> Micro -> (Int64, Micro)
    microQuotRem Micro
    t (Int64 -> Micro
    Micro 3600000000)
            (m :: Int64
    m, s :: Micro
    s) = Micro -> Micro -> (Int64, Micro)
    microQuotRem Micro
    ms (Int64 -> Micro
    Micro 60000000)

        {-# INLINEABLE toDiff #-}
        toDiff :: TimeOfDay -> DiffTime
        toDiff :: TimeOfDay -> DiffTime
    toDiff (TimeOfDay h :: Minutes
    h m :: Minutes
    m s :: DiffTime
    s) = DiffTime
    s
            DiffTime -> DiffTime -> DiffTime
    forall v. AdditiveGroup v => v -> v -> v
    ^+^ Minutes -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Minutes
    m Scalar DiffTime -> DiffTime -> DiffTime
    forall v. VectorSpace v => Scalar v -> v -> v
    *^ Micro -> DiffTime
    DiffTime (Int64 -> Micro
    Micro 60000000)
            DiffTime -> DiffTime -> DiffTime
    forall v. AdditiveGroup v => v -> v -> v
    ^+^ Minutes -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Minutes
    h Scalar DiffTime -> DiffTime -> DiffTime
    forall v. VectorSpace v => Scalar v -> v -> v
    *^ Micro -> DiffTime
    DiffTime (Int64 -> Micro
    Micro 3600000000)

    -- | Add some minutes to a 'TimeOfDay'; result comes with a day adjustment.
    {-# INLINE addMinutes #-}
    addMinutes :: Minutes -> TimeOfDay -> (Days, TimeOfDay)
    addMinutes :: Minutes -> TimeOfDay -> (Minutes, TimeOfDay)
    addMinutes dm :: Minutes
    dm (TimeOfDay h :: Minutes
    h m :: Minutes
    m s :: DiffTime
    s) = (Minutes
    dd, Minutes -> Minutes -> DiffTime -> TimeOfDay
    TimeOfDay Minutes
    h' Minutes
    m' DiffTime
    s) where
        (dd :: Minutes
    dd, h' :: Minutes
    h') = Minutes -> Minutes -> (Minutes, Minutes)
    forall a. Integral a => a -> a -> (a, a)
    divMod (Minutes
    h Minutes -> Minutes -> Minutes
    forall a. Num a => a -> a -> a
    + Minutes
    dh) 24
        (dh :: Minutes
    dh, m' :: Minutes
    m') = Minutes -> Minutes -> (Minutes, Minutes)
    forall a. Integral a => a -> a -> (a, a)
    divMod (Minutes
    m Minutes -> Minutes -> Minutes
    forall a. Num a => a -> a -> a
    + Minutes
    dm) 60

    {-# INLINE dayFraction #-}
    dayFraction :: Iso' TimeOfDay Rational
    dayFraction :: Overloaded p f TimeOfDay TimeOfDay Rational Rational
    dayFraction = AnIso DiffTime DiffTime TimeOfDay TimeOfDay
    -> Iso TimeOfDay TimeOfDay DiffTime DiffTime
    forall s t a b. AnIso s t a b -> Iso b a t s
    from AnIso DiffTime DiffTime TimeOfDay TimeOfDay
    Iso' DiffTime TimeOfDay
    timeOfDay Overloaded p f TimeOfDay TimeOfDay DiffTime DiffTime
    -> (p Rational (f Rational) -> p DiffTime (f DiffTime))
    -> Overloaded p f TimeOfDay TimeOfDay Rational Rational
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (DiffTime -> Rational)
    -> (Rational -> DiffTime)
    -> Iso DiffTime DiffTime Rational Rational
    forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
    iso DiffTime -> Rational
    toRatio Rational -> DiffTime
    fromRatio where

        {-# INLINEABLE toRatio #-}
        toRatio :: DiffTime -> Rational
        toRatio :: DiffTime -> Rational
    toRatio t :: DiffTime
    t = DiffTime -> Rational
    forall t n. (TimeDiff t, Fractional n) => t -> n
    toSeconds DiffTime
    t Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / NominalDiffTime -> Rational
    forall t n. (TimeDiff t, Fractional n) => t -> n
    toSeconds NominalDiffTime
    posixDayLength

        {-# INLINEABLE fromRatio #-}
        fromRatio :: Rational -> DiffTime
        fromRatio :: Rational -> DiffTime
    fromRatio ((Scalar NominalDiffTime -> NominalDiffTime -> NominalDiffTime
    forall v. VectorSpace v => Scalar v -> v -> v
    *^ NominalDiffTime
    posixDayLength) -> NominalDiffTime r :: Micro
    r) = Micro -> DiffTime
    DiffTime Micro
    r

    ------------------------------------------------------------------------
    -- * Local Time

    data LocalTime = LocalTime
        { LocalTime -> Day
    localDay :: {-# UNPACK #-}!Day
        , LocalTime -> TimeOfDay
    localTimeOfDay :: {-only 3 words…-} {-# UNPACK #-}!TimeOfDay
        } deriving (INSTANCES_USUAL)

    derivingUnbox "LocalTime" [t| LocalTime -> (Day, TimeOfDay) |]
        [| \ LocalTime {..} -> (localDay, localTimeOfDay) |]
        [| \ (localDay, localTimeOfDay) -> LocalTime {..} |]

    instance NFData LocalTime

    #if SHOW_INTERNAL
    deriving instance Show LocalTime
    #else
    instance Show LocalTime where
        showsPrec :: Minutes -> LocalTime -> ShowS
    showsPrec p :: Minutes
    p (LocalTime d :: Day
    d t :: TimeOfDay
    t) = Minutes -> Day -> ShowS
    forall a. Show a => Minutes -> a -> ShowS
    showsPrec Minutes
    p Day
    d ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (:) ' ' ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Minutes -> TimeOfDay -> ShowS
    forall a. Show a => Minutes -> a -> ShowS
    showsPrec Minutes
    p TimeOfDay
    t
    #endif

    instance Bounded LocalTime where
        minBound :: LocalTime
    minBound = UTCTime
    forall a. Bounded a => a
    minBound UTCTime -> Getting LocalTime UTCTime LocalTime -> LocalTime
    forall s a. s -> Getting a s a -> a
    ^. TimeZone -> Iso' UTCTime LocalTime
    utcLocalTime TimeZone
    forall a. Bounded a => a
    maxBound
        maxBound :: LocalTime
    maxBound = UTCTime
    forall a. Bounded a => a
    maxBound UTCTime -> Getting LocalTime UTCTime LocalTime -> LocalTime
    forall s a. s -> Getting a s a -> a
    ^. TimeZone -> Iso' UTCTime LocalTime
    utcLocalTime TimeZone
    forall a. Bounded a => a
    minBound

    instance Random LocalTime where
        randomR :: (LocalTime, LocalTime) -> g -> (LocalTime, g)
    randomR = Iso' UTCTime LocalTime
    -> (LocalTime, LocalTime) -> g -> (LocalTime, g)
    forall s g a.
    (Random s, RandomGen g) =>
    Iso' s a -> (a, a) -> g -> (a, g)
    randomIsoR (TimeZone -> Iso' UTCTime LocalTime
    utcLocalTime TimeZone
    utc)
        random :: g -> (LocalTime, g)
    random = (LocalTime, LocalTime) -> g -> (LocalTime, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (LocalTime
    forall a. Bounded a => a
    minBound, LocalTime
    forall a. Bounded a => a
    maxBound)

    instance Arbitrary LocalTime where
        arbitrary :: Gen LocalTime
    arbitrary = (LocalTime, LocalTime) -> Gen LocalTime
    forall a. Random a => (a, a) -> Gen a
    choose (LocalTime
    forall a. Bounded a => a
    minBound, LocalTime
    forall a. Bounded a => a
    maxBound)
        shrink :: LocalTime -> [LocalTime]
    shrink lt :: LocalTime
    lt@LocalTime {..}
            = [ LocalTime
    lt {localDay :: Day
    localDay = Day
    d} | Day
    d <- Day -> [Day]
    forall a. Arbitrary a => a -> [a]
    shrink Day
    localDay ]
            [LocalTime] -> [LocalTime] -> [LocalTime]
    forall a. [a] -> [a] -> [a]
    ++ [ LocalTime
    lt {localTimeOfDay :: TimeOfDay
    localTimeOfDay = TimeOfDay
    d} | TimeOfDay
    d <- TimeOfDay -> [TimeOfDay]
    forall a. Arbitrary a => a -> [a]
    shrink TimeOfDay
    localTimeOfDay ]

    instance CoArbitrary LocalTime where
        coarbitrary :: LocalTime -> Gen b -> Gen b
    coarbitrary (LocalTime d :: Day
    d t :: TimeOfDay
    t) = Day -> Gen b -> Gen b
    forall a b. CoArbitrary a => a -> Gen b -> Gen b
    coarbitrary Day
    d (Gen b -> Gen b) -> (Gen b -> Gen b) -> Gen b -> Gen b
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . TimeOfDay -> Gen b -> Gen b
    forall a b. CoArbitrary a => a -> Gen b -> Gen b
    coarbitrary TimeOfDay
    t

    {-# INLINE utcLocalTime #-}
    utcLocalTime :: TimeZone -> Iso' UTCTime LocalTime
    utcLocalTime :: TimeZone -> Iso' UTCTime LocalTime
    utcLocalTime TimeZone {..} = Overloaded p f UTCTime UTCTime UTCView UTCView
    Iso' UTCTime UTCView
    utcTime Overloaded p f UTCTime UTCTime UTCView UTCView
    -> (p LocalTime (f LocalTime) -> p UTCView (f UTCView))
    -> p LocalTime (f LocalTime)
    -> p UTCTime (f UTCTime)
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (UTCView -> LocalTime)
    -> (LocalTime -> UTCView)
    -> Iso UTCView UTCView LocalTime LocalTime
    forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
    iso UTCView -> LocalTime
    localise LocalTime -> UTCView
    globalise where

        {-# INLINEABLE localise #-}
        localise :: UTCView -> LocalTime
        localise :: UTCView -> LocalTime
    localise (UTCTime day :: Day
    day dt :: DiffTime
    dt) = Day -> TimeOfDay -> LocalTime
    LocalTime (Day
    day Day -> Diff Day -> Day
    forall p. AffineSpace p => p -> Diff p -> p
    .+^ Minutes
    Diff Day
    dd) TimeOfDay
    tod where
            (dd :: Minutes
    dd, tod :: TimeOfDay
    tod) = Minutes -> TimeOfDay -> (Minutes, TimeOfDay)
    addMinutes Minutes
    timeZoneMinutes (DiffTime
    dt DiffTime -> Getting TimeOfDay DiffTime TimeOfDay -> TimeOfDay
    forall s a. s -> Getting a s a -> a
    ^. Getting TimeOfDay DiffTime TimeOfDay
    Iso' DiffTime TimeOfDay
    timeOfDay)

        {-# INLINEABLE globalise #-}
        globalise :: LocalTime -> UTCView
        globalise :: LocalTime -> UTCView
    globalise (LocalTime day :: Day
    day tod :: TimeOfDay
    tod) = Day -> DiffTime -> UTCView
    UTCTime (Day
    day Day -> Diff Day -> Day
    forall p. AffineSpace p => p -> Diff p -> p
    .+^ Minutes
    Diff Day
    dd)
                (Overloaded Reviewed Identity DiffTime DiffTime TimeOfDay TimeOfDay
    Iso' DiffTime TimeOfDay
    timeOfDay Overloaded Reviewed Identity DiffTime DiffTime TimeOfDay TimeOfDay
    -> TimeOfDay -> DiffTime
    forall s t a b. AReview s t a b -> b -> t
    # TimeOfDay
    utcToD) where
            (dd :: Minutes
    dd, utcToD :: TimeOfDay
    utcToD) = Minutes -> TimeOfDay -> (Minutes, TimeOfDay)
    addMinutes (Minutes -> Minutes
    forall a. Num a => a -> a
    negate Minutes
    timeZoneMinutes) TimeOfDay
    tod

    {-# INLINE ut1LocalTime #-}
    ut1LocalTime :: Rational -> Iso' UniversalTime LocalTime
    ut1LocalTime :: Rational -> Iso' UniversalTime LocalTime
    ut1LocalTime long :: Rational
    long = (UniversalTime -> LocalTime)
    -> (LocalTime -> UniversalTime) -> Iso' UniversalTime LocalTime
    forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
    iso UniversalTime -> LocalTime
    localise LocalTime -> UniversalTime
    globalise where
        NominalDiffTime posixDay :: Micro
    posixDay@(Micro usDay :: Int64
    usDay) = NominalDiffTime
    posixDayLength

        {-# INLINEABLE localise #-}
        localise :: UniversalTime -> LocalTime
        localise :: UniversalTime -> LocalTime
    localise (UniversalRep (NominalDiffTime t :: Micro
    t)) = Day -> TimeOfDay -> LocalTime
    LocalTime
                (Minutes -> Day
    ModifiedJulianDay (Minutes -> Day) -> Minutes -> Day
    forall a b. (a -> b) -> a -> b
    $ Int64 -> Minutes
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int64
    day)
                (Micro -> DiffTime
    DiffTime Micro
    dt DiffTime -> Getting TimeOfDay DiffTime TimeOfDay -> TimeOfDay
    forall s a. s -> Getting a s a -> a
    ^. Getting TimeOfDay DiffTime TimeOfDay
    Iso' DiffTime TimeOfDay
    timeOfDay) where
            (day :: Int64
    day, dt :: Micro
    dt) = Micro -> Micro -> (Int64, Micro)
    microDivMod (Micro
    t Micro -> Micro -> Micro
    forall v. AdditiveGroup v => v -> v -> v
    ^+^ (Rational
    long Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / 360) Scalar Micro -> Micro -> Micro
    forall v. VectorSpace v => Scalar v -> v -> v
    *^ Micro
    posixDay) Micro
    posixDay

        {-# INLINEABLE globalise #-}
        globalise :: LocalTime -> UniversalTime
        globalise :: LocalTime -> UniversalTime
    globalise (LocalTime day :: Day
    day tod :: TimeOfDay
    tod) = NominalDiffTime -> UniversalTime
    UniversalRep (NominalDiffTime -> UniversalTime)
    -> (Micro -> NominalDiffTime) -> Micro -> UniversalTime
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Micro -> NominalDiffTime
    NominalDiffTime (Micro -> UniversalTime) -> Micro -> UniversalTime
    forall a b. (a -> b) -> a -> b
    $
                Int64 -> Micro
    Micro (Int64
    mjd Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    * Int64
    usDay) Micro -> Micro -> Micro
    forall v. AdditiveGroup v => v -> v -> v
    ^+^ Micro
    dt Micro -> Micro -> Micro
    forall v. AdditiveGroup v => v -> v -> v
    ^-^ (Rational
    long Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / 360) Scalar Micro -> Micro -> Micro
    forall v. VectorSpace v => Scalar v -> v -> v
    *^ Micro
    posixDay where
            ModifiedJulianDay (Minutes -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral -> Int64
    mjd) = Day
    day
            DiffTime dt :: Micro
    dt = Overloaded Reviewed Identity DiffTime DiffTime TimeOfDay TimeOfDay
    Iso' DiffTime TimeOfDay
    timeOfDay Overloaded Reviewed Identity DiffTime DiffTime TimeOfDay TimeOfDay
    -> TimeOfDay -> DiffTime
    forall s t a b. AReview s t a b -> b -> t
    # TimeOfDay
    tod

    ------------------------------------------------------------------------
    -- * Zoned Time

    data ZonedTime = ZonedTime
        { ZonedTime -> LocalTime
    zonedTimeToLocalTime :: {-only 4 words…-} {-# UNPACK #-}!LocalTime
        , ZonedTime -> TimeZone
    zonedTimeZone :: !TimeZone
        } deriving (INSTANCES_USUAL)

    instance NFData ZonedTime where
        rnf :: ZonedTime -> ()
    rnf ZonedTime {..} = TimeZone -> ()
    forall a. NFData a => a -> ()
    rnf TimeZone
    zonedTimeZone

    instance Bounded ZonedTime where
        minBound :: ZonedTime
    minBound = LocalTime -> TimeZone -> ZonedTime
    ZonedTime LocalTime
    forall a. Bounded a => a
    minBound TimeZone
    forall a. Bounded a => a
    maxBound
        maxBound :: ZonedTime
    maxBound = LocalTime -> TimeZone -> ZonedTime
    ZonedTime LocalTime
    forall a. Bounded a => a
    maxBound TimeZone
    forall a. Bounded a => a
    minBound

    instance Random ZonedTime where
        randomR :: (ZonedTime, ZonedTime) -> g -> (ZonedTime, g)
    randomR (l :: ZonedTime
    l, u :: ZonedTime
    u) g0 :: g
    g0 = (Getting ZonedTime (TimeZone, UTCTime) ZonedTime
    -> (TimeZone, UTCTime) -> ZonedTime
    forall a s. Getting a s a -> s -> a
    view Getting ZonedTime (TimeZone, UTCTime) ZonedTime
    Iso' (TimeZone, UTCTime) ZonedTime
    zonedTime ((TimeZone, UTCTime) -> ZonedTime)
    -> (UTCTime -> (TimeZone, UTCTime)) -> UTCTime -> ZonedTime
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (,) TimeZone
    tz)
                (UTCTime -> ZonedTime) -> (UTCTime, g) -> (ZonedTime, g)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    `first` (UTCTime, UTCTime) -> g -> (UTCTime, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (UTCTime
    l', UTCTime
    u') g
    g1 where
            (tz :: TimeZone
    tz, g1 :: g
    g1) = g -> (TimeZone, g)
    forall a g. (Random a, RandomGen g) => g -> (a, g)
    random g
    g0 -- ignore TimeZone from l and u
            l' :: UTCTime
    l' = (TimeZone, UTCTime) -> UTCTime
    forall a b. (a, b) -> b
    snd ((TimeZone, UTCTime) -> UTCTime) -> (TimeZone, UTCTime) -> UTCTime
    forall a b. (a -> b) -> a -> b
    $ Overloaded
      Reviewed
      Identity
      (TimeZone, UTCTime)
      (TimeZone, UTCTime)
      ZonedTime
      ZonedTime
    Iso' (TimeZone, UTCTime) ZonedTime
    zonedTime Overloaded
      Reviewed
      Identity
      (TimeZone, UTCTime)
      (TimeZone, UTCTime)
      ZonedTime
      ZonedTime
    -> ZonedTime -> (TimeZone, UTCTime)
    forall s t a b. AReview s t a b -> b -> t
    # ZonedTime
    l
            u' :: UTCTime
    u' = (TimeZone, UTCTime) -> UTCTime
    forall a b. (a, b) -> b
    snd ((TimeZone, UTCTime) -> UTCTime) -> (TimeZone, UTCTime) -> UTCTime
    forall a b. (a -> b) -> a -> b
    $ Overloaded
      Reviewed
      Identity
      (TimeZone, UTCTime)
      (TimeZone, UTCTime)
      ZonedTime
      ZonedTime
    Iso' (TimeZone, UTCTime) ZonedTime
    zonedTime Overloaded
      Reviewed
      Identity
      (TimeZone, UTCTime)
      (TimeZone, UTCTime)
      ZonedTime
      ZonedTime
    -> ZonedTime -> (TimeZone, UTCTime)
    forall s t a b. AReview s t a b -> b -> t
    # ZonedTime
    u
        random :: g -> (ZonedTime, g)
    random = (ZonedTime, ZonedTime) -> g -> (ZonedTime, g)
    forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
    randomR (ZonedTime
    forall a. Bounded a => a
    minBound, ZonedTime
    forall a. Bounded a => a
    maxBound)

    instance Arbitrary ZonedTime where
        arbitrary :: Gen ZonedTime
    arbitrary = (ZonedTime, ZonedTime) -> Gen ZonedTime
    forall a. Random a => (a, a) -> Gen a
    choose (ZonedTime
    forall a. Bounded a => a
    minBound, ZonedTime
    forall a. Bounded a => a
    maxBound)
        shrink :: ZonedTime -> [ZonedTime]
    shrink zt :: ZonedTime
    zt@ZonedTime {..}
            = [ ZonedTime
    zt {zonedTimeToLocalTime :: LocalTime
    zonedTimeToLocalTime = LocalTime
    lt} | LocalTime
    lt <- LocalTime -> [LocalTime]
    forall a. Arbitrary a => a -> [a]
    shrink LocalTime
    zonedTimeToLocalTime ]
            [ZonedTime] -> [ZonedTime] -> [ZonedTime]
    forall a. [a] -> [a] -> [a]
    ++ [ ZonedTime
    zt {zonedTimeZone :: TimeZone
    zonedTimeZone = TimeZone
    tz} | TimeZone
    tz <- TimeZone -> [TimeZone]
    forall a. Arbitrary a => a -> [a]
    shrink TimeZone
    zonedTimeZone ]

    instance CoArbitrary ZonedTime where
        coarbitrary :: ZonedTime -> Gen b -> Gen b
    coarbitrary (ZonedTime lt :: LocalTime
    lt tz :: TimeZone
    tz) = LocalTime -> Gen b -> Gen b
    forall a b. CoArbitrary a => a -> Gen b -> Gen b
    coarbitrary LocalTime
    lt (Gen b -> Gen b) -> (Gen b -> Gen b) -> Gen b -> Gen b
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . TimeZone -> Gen b -> Gen b
    forall a b. CoArbitrary a => a -> Gen b -> Gen b
    coarbitrary TimeZone
    tz

    {-# INLINE zonedTime #-}
    zonedTime :: Iso' (TimeZone, UTCTime) ZonedTime
    zonedTime :: Overloaded
      p f (TimeZone, UTCTime) (TimeZone, UTCTime) ZonedTime ZonedTime
    zonedTime = ((TimeZone, UTCTime) -> ZonedTime)
    -> (ZonedTime -> (TimeZone, UTCTime))
    -> Iso' (TimeZone, UTCTime) ZonedTime
    forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
    iso (TimeZone, UTCTime) -> ZonedTime
    toZoned ZonedTime -> (TimeZone, UTCTime)
    fromZoned where

        {-# INLINE toZoned #-}
        toZoned :: (TimeZone, UTCTime) -> ZonedTime
        toZoned :: (TimeZone, UTCTime) -> ZonedTime
    toZoned (tz :: TimeZone
    tz, time :: UTCTime
    time) = LocalTime -> TimeZone -> ZonedTime
    ZonedTime (UTCTime
    time UTCTime -> Getting LocalTime UTCTime LocalTime -> LocalTime
    forall s a. s -> Getting a s a -> a
    ^. TimeZone -> Iso' UTCTime LocalTime
    utcLocalTime TimeZone
    tz) TimeZone
    tz

        {-# INLINE fromZoned #-}
        fromZoned :: ZonedTime -> (TimeZone, UTCTime)
        fromZoned :: ZonedTime -> (TimeZone, UTCTime)
    fromZoned (ZonedTime lt :: LocalTime
    lt tz :: TimeZone
    tz) = (TimeZone
    tz, TimeZone -> Iso' UTCTime LocalTime
    utcLocalTime TimeZone
    tz Overloaded Reviewed Identity UTCTime UTCTime LocalTime LocalTime
    -> LocalTime -> UTCTime
    forall s t a b. AReview s t a b -> b -> t
    # LocalTime
    lt)

    #if SHOW_INTERNAL
    deriving instance Show ZonedTime
    instance Show UTCTime where
        showsPrec p = showsPrec p . view utcTime
    #else
    instance Show ZonedTime where
        showsPrec :: Minutes -> ZonedTime -> ShowS
    showsPrec p :: Minutes
    p (ZonedTime lt :: LocalTime
    lt tz :: TimeZone
    tz) = Minutes -> LocalTime -> ShowS
    forall a. Show a => Minutes -> a -> ShowS
    showsPrec Minutes
    p LocalTime
    lt ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (:) ' ' ShowS -> ShowS -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Minutes -> TimeZone -> ShowS
    forall a. Show a => Minutes -> a -> ShowS
    showsPrec Minutes
    p TimeZone
    tz
    instance Show UTCTime where
        showsPrec :: Minutes -> UTCTime -> ShowS
    showsPrec p :: Minutes
    p = Minutes -> ZonedTime -> ShowS
    forall a. Show a => Minutes -> a -> ShowS
    showsPrec Minutes
    p (ZonedTime -> ShowS) -> (UTCTime -> ZonedTime) -> UTCTime -> ShowS
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Getting ZonedTime (TimeZone, UTCTime) ZonedTime
    -> (TimeZone, UTCTime) -> ZonedTime
    forall a s. Getting a s a -> s -> a
    view Getting ZonedTime (TimeZone, UTCTime) ZonedTime
    Iso' (TimeZone, UTCTime) ZonedTime
    zonedTime ((TimeZone, UTCTime) -> ZonedTime)
    -> (UTCTime -> (TimeZone, UTCTime)) -> UTCTime -> ZonedTime
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (,) TimeZone
    utc
    #endif

    {-# INLINE getZonedTime #-}
    getZonedTime :: IO ZonedTime
    getZonedTime :: IO ZonedTime
    getZonedTime = UTCTime -> IO ZonedTime
    utcToLocalZonedTime (UTCTime -> IO ZonedTime) -> IO UTCTime -> IO ZonedTime
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< IO UTCTime
    getCurrentTime

    {-# INLINEABLE utcToLocalZonedTime #-}
    utcToLocalZonedTime :: UTCTime -> IO ZonedTime
    utcToLocalZonedTime :: UTCTime -> IO ZonedTime
    utcToLocalZonedTime time :: UTCTime
    time = do
        TimeZone
    tz <- UTCTime -> IO TimeZone
    getTimeZone UTCTime
    time
        ZonedTime -> IO ZonedTime
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ZonedTime -> IO ZonedTime) -> ZonedTime -> IO ZonedTime
    forall a b. (a -> b) -> a -> b
    $ (TimeZone
    tz, UTCTime
    time) (TimeZone, UTCTime)
    -> Getting ZonedTime (TimeZone, UTCTime) ZonedTime -> ZonedTime
    forall s a. s -> Getting a s a -> a
    ^. Getting ZonedTime (TimeZone, UTCTime) ZonedTime
    Iso' (TimeZone, UTCTime) ZonedTime
    zonedTime

    -- * Lenses

    LENS(TimeZone,timeZoneMinutes,Minutes)
    LENS(TimeZone,timeZoneSummerOnly,Bool)
    LENS(TimeZone,timeZoneName,String)

    LENS(TimeOfDay,todHour,Hour)
    LENS(TimeOfDay,todMin,Minute)
    LENS(TimeOfDay,todSec,DiffTime)

    LENS(LocalTime,localDay,Day)
    LENS(LocalTime,localTimeOfDay,TimeOfDay)

    LENS(ZonedTime,zonedTimeToLocalTime,LocalTime)
    LENS(ZonedTime,zonedTimeZone,TimeZone)