    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE FlexibleContexts #-} -- workaround
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE RecordWildCards #-}
    {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE ViewPatterns #-}
    {-# OPTIONS_HADDOCK hide #-}

    #include "thyme.h"

    module Data.Thyme.Clock.Internal where

    import Prelude
    import Control.DeepSeq
    import Control.Lens
    import Data.AdditiveGroup
    import Data.AffineSpace
    import Data.Basis
    import Data.Data
    import Data.Int
    import Data.Ix
    import Data.Thyme.Internal.Micro
    import Data.Thyme.Calendar.Internal
    #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

    #if !SHOW_INTERNAL
    import Control.Monad
    import Text.ParserCombinators.ReadPrec (lift)
    import Text.ParserCombinators.ReadP (char)
    import Text.Read (readPrec)
    #endif

    -- | Time intervals, encompassing both 'DiffTime' and 'NominalDiffTime'.
    --
    -- [@Issues@] Still affected by
    -- <http://hackage.haskell.org/trac/ghc/ticket/7611>?
    class (HasBasis t, Basis t ~ (), Scalar t ~ Rational) => TimeDiff t where
        -- | Escape hatch; avoid.
        microseconds :: Iso' t Int64

    -- | Convert a time interval to some 'Fractional' type.
    {-# INLINE toSeconds #-}
    toSeconds :: (TimeDiff t, Fractional n) => t -> n
    toSeconds :: t -> n
    toSeconds = (n -> n -> n
    forall a. Num a => a -> a -> a
    * n -> n
    forall a. Fractional a => a -> a
    recip 1000000) (n -> n) -> (t -> n) -> t -> n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> n
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int64 -> n) -> (t -> Int64) -> t -> n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Getting Int64 t Int64 -> t -> Int64
    forall a s. Getting a s a -> s -> a
    view Getting Int64 t Int64
    forall t. TimeDiff t => Iso' t Int64
    microseconds

    -- | Make a time interval from some 'Real' type.
    --
    -- [@Performance@] Try to make sure @n@ is one of 'Float', 'Double', 'Int',
    -- 'Int64' or 'Integer', for which rewrite @RULES@ have been provided.
    {-# INLINE[0] fromSeconds #-}
    fromSeconds :: (Real n, TimeDiff t) => n -> t
    fromSeconds :: n -> t
    fromSeconds = Rational -> t
    forall t. TimeDiff t => Rational -> t
    fromSeconds' (Rational -> t) -> (n -> Rational) -> n -> t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . n -> Rational
    forall a. Real a => a -> Rational
    toRational

    -- | Type-restricted 'toSeconds' to avoid constraint-defaulting warnings.
    {-# INLINE toSeconds' #-}
    toSeconds' :: (TimeDiff t) => t -> Rational
    toSeconds' :: t -> Rational
    toSeconds' = (t -> Basis t -> Scalar t
    forall v. HasBasis v => v -> Basis v -> Scalar v
    `decompose'` ())

    -- | Type-restricted 'fromSeconds' to avoid constraint-defaulting warnings.
    {-# INLINE fromSeconds' #-}
    fromSeconds' :: (TimeDiff t) => Rational -> t
    fromSeconds' :: Rational -> t
    fromSeconds' = (Scalar t -> t -> t
    forall v. VectorSpace v => Scalar v -> v -> v
    *^ Basis t -> t
    forall v. HasBasis v => Basis v -> v
    basisValue ())

    {-# INLINE picoseconds #-}
    picoseconds :: (TimeDiff t) => Iso' t Integer
    picoseconds :: Iso' t Integer
    picoseconds = Overloaded p f t t Int64 Int64
    forall t. TimeDiff t => Iso' t Int64
    microseconds Overloaded p f t t Int64 Int64
    -> (p Integer (f Integer) -> p Int64 (f Int64))
    -> p Integer (f Integer)
    -> p t (f t)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int64 -> Integer)
    -> (Integer -> Int64) -> Iso Int64 Int64 Integer Integer
    forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
    iso (Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    (*) 1000000 (Integer -> Integer) -> (Int64 -> Integer) -> Int64 -> Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Integer
    forall a. Integral a => a -> Integer
    toInteger)
        (\ ps :: Integer
    ps -> Integer -> Int64
    forall a. Num a => Integer -> a
    fromInteger (Integer -> Int64) -> Integer -> Int64
    forall a b. (a -> b) -> a -> b
    $ Integer -> Integer -> Integer
    forall a. Integral a => a -> a -> a
    quot (Integer
    ps Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Integer -> Integer
    forall a. Num a => a -> a
    signum Integer
    ps Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    * 500000) 1000000)

    ------------------------------------------------------------------------
    -- not for public consumption

    {-# INLINE fromSecondsRealFrac #-}
    fromSecondsRealFrac :: (RealFrac n, TimeDiff t) => n -> n -> t
    fromSecondsRealFrac :: n -> n -> t
    fromSecondsRealFrac _ = AReview t t Int64 Int64 -> Int64 -> t
    forall s t a b. AReview s t a b -> b -> t
    review AReview t t Int64 Int64
    forall t. TimeDiff t => Iso' t Int64
    microseconds (Int64 -> t) -> (n -> Int64) -> n -> t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . n -> Int64
    forall a b. (RealFrac a, Integral b) => a -> b
    round (n -> Int64) -> (n -> n) -> n -> Int64
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . n -> n -> n
    forall a. Num a => a -> a -> a
    (*) 1000000

    {-# INLINE fromSecondsIntegral #-}
    fromSecondsIntegral :: (Integral n, TimeDiff t) => n -> n -> t
    fromSecondsIntegral :: n -> n -> t
    fromSecondsIntegral _ = AReview t t Int64 Int64 -> Int64 -> t
    forall s t a b. AReview s t a b -> b -> t
    review AReview t t Int64 Int64
    forall t. TimeDiff t => Iso' t Int64
    microseconds (Int64 -> t) -> (n -> Int64) -> n -> t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    (*) 1000000 (Int64 -> Int64) -> (n -> Int64) -> n -> Int64
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . n -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral

    {-# RULES

    "fromSeconds/Float"    [~0] fromSeconds = fromSecondsRealFrac (0 :: Float)
    "fromSeconds/Double"   [~0] fromSeconds = fromSecondsRealFrac (0 :: Double)
    "fromSeconds/Int"      [~0] fromSeconds = fromSecondsIntegral (0 :: Int)
    "fromSeconds/Int64"    [~0] fromSeconds = fromSecondsIntegral (0 :: Int64)
    "fromSeconds/Integer"  [~0] fromSeconds = fromSecondsIntegral (0 :: Integer)

      #-}

    ------------------------------------------------------------------------

    -- | An absolute time interval as measured by a clock.
    --
    -- 'DiffTime' forms an 'AdditiveGroup'―so can be added using '^+^' (or '^-^'
    -- for subtraction), and also an instance of 'VectorSpace'―so can be scaled
    -- using '*^', where
    --
    -- @
    -- type 'Scalar' 'DiffTime' = 'Rational'
    -- @
    newtype DiffTime = DiffTime Micro deriving (INSTANCES_MICRO, AdditiveGroup)

    derivingUnbox "DiffTime" [t| DiffTime -> Micro |]
        [| \ (DiffTime a) -> a |] [| DiffTime |]

    #if SHOW_INTERNAL
    deriving instance Show DiffTime
    deriving instance Read DiffTime
    #else
    instance Show DiffTime where
        {-# INLINEABLE showsPrec #-}
        showsPrec :: Int -> DiffTime -> ShowS
    showsPrec p :: Int
    p (DiffTime a :: Micro
    a) = Int -> Micro -> ShowS
    forall a. Show a => Int -> a -> ShowS
    showsPrec Int
    p Micro
    a ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (:) 's'
    instance Read DiffTime where
        {-# INLINEABLE readPrec #-}
        readPrec :: ReadPrec DiffTime
    readPrec = (Micro -> Char -> DiffTime) -> ReadPrec (Micro -> Char -> DiffTime)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (DiffTime -> Char -> DiffTime
    forall a b. a -> b -> a
    const (DiffTime -> Char -> DiffTime)
    -> (Micro -> DiffTime) -> Micro -> Char -> DiffTime
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Micro -> DiffTime
    DiffTime) ReadPrec (Micro -> Char -> DiffTime)
    -> ReadPrec Micro -> ReadPrec (Char -> DiffTime)
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    `ap` ReadPrec Micro
    forall a. Read a => ReadPrec a
    readPrec ReadPrec (Char -> DiffTime) -> ReadPrec Char -> ReadPrec DiffTime
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    `ap` ReadP Char -> ReadPrec Char
    forall a. ReadP a -> ReadPrec a
    lift (Char -> ReadP Char
    char 's')
    #endif

    instance VectorSpace DiffTime where
        type Scalar DiffTime = Rational
        {-# INLINE (*^) #-}
        *^ :: Scalar DiffTime -> DiffTime -> DiffTime
    (*^) = \ s :: Scalar DiffTime
    s (DiffTime t :: Micro
    t) -> Micro -> DiffTime
    DiffTime (Scalar Micro
    Scalar DiffTime
    s Scalar Micro -> Micro -> Micro
    forall v. VectorSpace v => Scalar v -> v -> v
    *^ Micro
    t)

    instance HasBasis DiffTime where
        type Basis DiffTime = ()
        {-# INLINE basisValue #-}
        basisValue :: Basis DiffTime -> DiffTime
    basisValue = \ _ -> Micro -> DiffTime
    DiffTime (Basis Micro -> Micro
    forall v. HasBasis v => Basis v -> v
    basisValue ())
        {-# INLINE decompose #-}
        decompose :: DiffTime -> [(Basis DiffTime, Scalar DiffTime)]
    decompose = \ (DiffTime a :: Micro
    a) -> Micro -> [(Basis Micro, Scalar Micro)]
    forall v. HasBasis v => v -> [(Basis v, Scalar v)]
    decompose Micro
    a
        {-# INLINE decompose' #-}
        decompose' :: DiffTime -> Basis DiffTime -> Scalar DiffTime
    decompose' = \ (DiffTime a :: Micro
    a) -> Micro -> Basis Micro -> Scalar Micro
    forall v. HasBasis v => v -> Basis v -> Scalar v
    decompose' Micro
    a

    instance TimeDiff DiffTime where
        {-# INLINE microseconds #-}
        microseconds :: Overloaded p f DiffTime DiffTime Int64 Int64
    microseconds = (DiffTime -> Int64) -> (Int64 -> DiffTime) -> Iso' DiffTime Int64
    forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
    iso (\ (DiffTime (Micro u :: Int64
    u)) -> Int64
    u) (Micro -> DiffTime
    DiffTime (Micro -> DiffTime) -> (Int64 -> Micro) -> Int64 -> DiffTime
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Micro
    Micro)

    ------------------------------------------------------------------------

    -- | A time interval as measured by UTC, that does not take leap-seconds
    -- into account.
    --
    -- For instance, the difference between @23:59:59@ and @00:00:01@ on the
    -- following day is always 2 seconds of 'NominalDiffTime', regardless of
    -- whether a leap-second took place.
    --
    -- 'NominalDiffTime' forms an 'AdditiveGroup'―so can be added using '^+^'
    -- (or '^-^' for subtraction), and also an instance of 'VectorSpace'―so can
    -- be scaled using '*^', where
    --
    -- @
    -- type 'Scalar' 'NominalDiffTime' = 'Rational'
    -- @
    newtype NominalDiffTime = NominalDiffTime Micro deriving (INSTANCES_MICRO, AdditiveGroup)

    derivingUnbox "NominalDiffTime" [t| NominalDiffTime -> Micro |]
        [| \ (NominalDiffTime a) -> a |] [| NominalDiffTime |]

    #if SHOW_INTERNAL
    deriving instance Show NominalDiffTime
    deriving instance Read NominalDiffTime
    #else
    instance Show NominalDiffTime where
        {-# INLINEABLE showsPrec #-}
        showsPrec :: Int -> NominalDiffTime -> ShowS
    showsPrec p :: Int
    p (NominalDiffTime a :: Micro
    a) rest :: String
    rest = Int -> Micro -> ShowS
    forall a. Show a => Int -> a -> ShowS
    showsPrec Int
    p Micro
    a ('s' Char -> ShowS
    forall a. a -> [a] -> [a]
    : String
    rest)
    instance Read NominalDiffTime where
        {-# INLINEABLE readPrec #-}
        readPrec :: ReadPrec NominalDiffTime
    readPrec = (Micro -> Char -> NominalDiffTime)
    -> ReadPrec (Micro -> Char -> NominalDiffTime)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (NominalDiffTime -> Char -> NominalDiffTime
    forall a b. a -> b -> a
    const (NominalDiffTime -> Char -> NominalDiffTime)
    -> (Micro -> NominalDiffTime) -> Micro -> Char -> NominalDiffTime
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Micro -> NominalDiffTime
    NominalDiffTime) ReadPrec (Micro -> Char -> NominalDiffTime)
    -> ReadPrec Micro -> ReadPrec (Char -> NominalDiffTime)
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    `ap` ReadPrec Micro
    forall a. Read a => ReadPrec a
    readPrec ReadPrec (Char -> NominalDiffTime)
    -> ReadPrec Char -> ReadPrec NominalDiffTime
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    `ap` ReadP Char -> ReadPrec Char
    forall a. ReadP a -> ReadPrec a
    lift (Char -> ReadP Char
    char 's')
    #endif

    instance VectorSpace NominalDiffTime where
        type Scalar NominalDiffTime = Rational
        {-# INLINE (*^) #-}
        *^ :: Scalar NominalDiffTime -> NominalDiffTime -> NominalDiffTime
    (*^) = \ s :: Scalar NominalDiffTime
    s (NominalDiffTime t :: Micro
    t) -> Micro -> NominalDiffTime
    NominalDiffTime (Scalar Micro
    Scalar NominalDiffTime
    s Scalar Micro -> Micro -> Micro
    forall v. VectorSpace v => Scalar v -> v -> v
    *^ Micro
    t)

    instance HasBasis NominalDiffTime where
        type Basis NominalDiffTime = ()
        {-# INLINE basisValue #-}
        basisValue :: Basis NominalDiffTime -> NominalDiffTime
    basisValue = \ _ -> Micro -> NominalDiffTime
    NominalDiffTime (Basis Micro -> Micro
    forall v. HasBasis v => Basis v -> v
    basisValue ())
        {-# INLINE decompose #-}
        decompose :: NominalDiffTime
    -> [(Basis NominalDiffTime, Scalar NominalDiffTime)]
    decompose = \ (NominalDiffTime a :: Micro
    a) -> Micro -> [(Basis Micro, Scalar Micro)]
    forall v. HasBasis v => v -> [(Basis v, Scalar v)]
    decompose Micro
    a
        {-# INLINE decompose' #-}
        decompose' :: NominalDiffTime -> Basis NominalDiffTime -> Scalar NominalDiffTime
    decompose' = \ (NominalDiffTime a :: Micro
    a) -> Micro -> Basis Micro -> Scalar Micro
    forall v. HasBasis v => v -> Basis v -> Scalar v
    decompose' Micro
    a

    instance TimeDiff NominalDiffTime where
        {-# INLINE microseconds #-}
        microseconds :: Overloaded p f NominalDiffTime NominalDiffTime Int64 Int64
    microseconds = (NominalDiffTime -> Int64)
    -> (Int64 -> NominalDiffTime) -> Iso' NominalDiffTime Int64
    forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
    iso (\ (NominalDiffTime (Micro u :: Int64
    u)) -> Int64
    u) (Micro -> NominalDiffTime
    NominalDiffTime (Micro -> NominalDiffTime)
    -> (Int64 -> Micro) -> Int64 -> NominalDiffTime
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Micro
    Micro)

    -- | The nominal length of a POSIX day: precisely 86400 SI seconds.
    {-# INLINE posixDayLength #-}
    posixDayLength :: NominalDiffTime
    posixDayLength :: NominalDiffTime
    posixDayLength = Overloaded
      Reviewed Identity NominalDiffTime NominalDiffTime Int64 Int64
    forall t. TimeDiff t => Iso' t Int64
    microseconds Overloaded
      Reviewed Identity NominalDiffTime NominalDiffTime Int64 Int64
    -> Int64 -> NominalDiffTime
    forall s t a b. AReview s t a b -> b -> t
    # 86400000000

    ------------------------------------------------------------------------

    -- | The principal form of universal time, namely
    -- <http://en.wikipedia.org/wiki/Universal_Time#Versions UT1>.
    --
    -- 'UniversalTime' is defined by the rotation of the Earth around its axis
    -- relative to the Sun. Thus the length of a day by this definition varies
    -- from one to the next, and is never exactly 86400 SI seconds unlike
    -- <http://en.wikipedia.org/wiki/International_Atomic_Time TAI> or
    -- 'AbsoluteTime'. The difference between UT1 and UTC is
    -- <http://en.wikipedia.org/wiki/DUT1 DUT1>.
    newtype UniversalTime = UniversalRep NominalDiffTime deriving (INSTANCES_MICRO)

    derivingUnbox "UniversalTime" [t| UniversalTime -> NominalDiffTime |]
        [| \ (UniversalRep a) -> a |] [| UniversalRep |]

    -- | View 'UniversalTime' as a fractional number of days since the
    -- <http://en.wikipedia.org/wiki/Julian_day#Variants Modified Julian Date epoch>.
    {-# INLINE modJulianDate #-}
    modJulianDate :: Iso' UniversalTime Rational
    modJulianDate :: Overloaded p f UniversalTime UniversalTime Rational Rational
    modJulianDate = (UniversalTime -> Rational)
    -> (Rational -> UniversalTime)
    -> Iso UniversalTime UniversalTime Rational Rational
    forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
    iso
        (\ (UniversalRep t :: NominalDiffTime
    t) -> NominalDiffTime -> Rational
    forall t n. (TimeDiff t, Fractional n) => t -> n
    toSeconds NominalDiffTime
    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)
        (NominalDiffTime -> UniversalTime
    UniversalRep (NominalDiffTime -> UniversalTime)
    -> (Rational -> NominalDiffTime) -> Rational -> UniversalTime
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Scalar NominalDiffTime -> NominalDiffTime -> NominalDiffTime
    forall v. VectorSpace v => Scalar v -> v -> v
    *^ NominalDiffTime
    posixDayLength))

    ------------------------------------------------------------------------

    -- | <http://en.wikipedia.org/wiki/Coordinated_Universal_Time Coördinated universal time>:
    -- the most common form of universal time for civil timekeeping. It is
    -- synchronised with 'AbsoluteTime' and both tick in increments of SI
    -- seconds, but UTC includes occasional leap-seconds so that it does not
    -- drift too far from 'UniversalTime'.
    --
    -- 'UTCTime' is an instance of 'AffineSpace', with
    --
    -- @
    -- type 'Diff' 'UTCTime' = 'NominalDiffTime'
    -- @
    --
    -- Use '.+^' to add (or '.-^' to subtract) time intervals of type
    -- 'NominalDiffTime', and '.-.' to get the interval between 'UTCTime's.
    --
    -- [@Performance@] Internally this is a 64-bit count of 'microseconds' since
    -- the MJD epoch, so '.+^', '.-^' and '.-.' ought to be fairly fast.
    --
    -- [@Issues@] 'UTCTime' currently
    -- <https://github.com/liyang/thyme/issues/3 cannot represent leap seconds>.
    newtype UTCTime = UTCRep NominalDiffTime deriving (INSTANCES_MICRO)

    derivingUnbox "UTCTime" [t| UTCTime -> NominalDiffTime |]
        [| \ (UTCRep a) -> a |] [| UTCRep |]

    -- | Unpacked 'UTCTime', partly for compatibility with @time@.
    data UTCView = UTCTime
        { UTCView -> Day
    utctDay :: {-# UNPACK #-}!Day
        , UTCView -> DiffTime
    utctDayTime :: {-# UNPACK #-}!DiffTime
        } deriving (INSTANCES_USUAL, Show)

    derivingUnbox "UTCView" [t| UTCView -> (Day, DiffTime) |]
        [| \ UTCTime {..} -> (utctDay, utctDayTime) |]
        [| \ (utctDay, utctDayTime) -> UTCTime {..} |]

    instance NFData UTCView

    -- | 'Lens'' for the 'Day' component of an 'UTCTime'.
    _utctDay :: Lens' UTCTime Day
    _utctDay :: Overloaded (->) f UTCTime UTCTime Day Day
    _utctDay = Overloaded (->) f UTCTime UTCTime UTCView UTCView
    Iso' UTCTime UTCView
    utcTime Overloaded (->) f UTCTime UTCTime UTCView UTCView
    -> ((Day -> f Day) -> UTCView -> f UTCView)
    -> Overloaded (->) f UTCTime UTCTime Day Day
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (UTCView -> Day)
    -> (UTCView -> Day -> UTCView) -> Lens UTCView UTCView Day Day
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens UTCView -> Day
    utctDay (\ (UTCTime _ t :: DiffTime
    t) d :: Day
    d -> Day -> DiffTime -> UTCView
    UTCTime Day
    d DiffTime
    t)

    -- | 'Lens'' for the time-of-day component of an 'UTCTime'.
    _utctDayTime :: Lens' UTCTime DiffTime
    _utctDayTime :: Overloaded (->) f UTCTime UTCTime DiffTime DiffTime
    _utctDayTime = Overloaded (->) f UTCTime UTCTime UTCView UTCView
    Iso' UTCTime UTCView
    utcTime Overloaded (->) f UTCTime UTCTime UTCView UTCView
    -> ((DiffTime -> f DiffTime) -> UTCView -> f UTCView)
    -> Overloaded (->) f UTCTime UTCTime DiffTime DiffTime
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (UTCView -> DiffTime)
    -> (UTCView -> DiffTime -> UTCView)
    -> Lens UTCView UTCView DiffTime DiffTime
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens UTCView -> DiffTime
    utctDayTime (\ (UTCTime d :: Day
    d _) t :: DiffTime
    t -> Day -> DiffTime -> UTCView
    UTCTime Day
    d DiffTime
    t)

    instance AffineSpace UTCTime where
        type Diff UTCTime = NominalDiffTime
        {-# INLINE (.-.) #-}
        .-. :: UTCTime -> UTCTime -> Diff UTCTime
    (.-.) = \ (UTCRep a :: NominalDiffTime
    a) (UTCRep b :: NominalDiffTime
    b) -> NominalDiffTime
    a NominalDiffTime -> NominalDiffTime -> NominalDiffTime
    forall v. AdditiveGroup v => v -> v -> v
    ^-^ NominalDiffTime
    b
        {-# INLINE (.+^) #-}
        .+^ :: UTCTime -> Diff UTCTime -> UTCTime
    (.+^) = \ (UTCRep a :: NominalDiffTime
    a) d :: Diff UTCTime
    d -> NominalDiffTime -> UTCTime
    UTCRep (NominalDiffTime
    a NominalDiffTime -> NominalDiffTime -> NominalDiffTime
    forall v. AdditiveGroup v => v -> v -> v
    ^+^ Diff UTCTime
    NominalDiffTime
    d)

    -- | View 'UTCTime' as an 'UTCView', comprising a 'Day' along with
    -- a 'DiffTime' offset since midnight.
    --
    -- This is an improper lens: 'utctDayTime' offsets outside the range of
    -- @['zeroV', 'posixDayLength')@ will carry over into the day part, with the
    -- expected behaviour.
    {-# INLINE utcTime #-}
    utcTime :: Iso' UTCTime UTCView
    utcTime :: Overloaded p f UTCTime UTCTime UTCView UTCView
    utcTime = (UTCTime -> UTCView)
    -> (UTCView -> UTCTime) -> Iso' UTCTime UTCView
    forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
    iso UTCTime -> UTCView
    toView UTCView -> UTCTime
    fromView where
        NominalDiffTime posixDay :: Micro
    posixDay@(Micro uPosixDay :: Int64
    uPosixDay) = NominalDiffTime
    posixDayLength

        {-# INLINE toView #-}
        toView :: UTCTime -> UTCView
        toView :: UTCTime -> UTCView
    toView (UTCRep (NominalDiffTime a :: Micro
    a)) = Day -> DiffTime -> UTCView
    UTCTime
                (Int -> Day
    ModifiedJulianDay Int
    mjd) (Micro -> DiffTime
    DiffTime Micro
    dt) where
            (Int64 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral -> Int
    mjd, dt :: Micro
    dt) = Micro -> Micro -> (Int64, Micro)
    microDivMod Micro
    a Micro
    posixDay

        {-# INLINE fromView #-}
        fromView :: UTCView -> UTCTime
        fromView :: UTCView -> UTCTime
    fromView (UTCTime (ModifiedJulianDay mjd :: Int
    mjd) (DiffTime dt :: Micro
    dt)) = NominalDiffTime -> UTCTime
    UTCRep NominalDiffTime
    a where
            a :: NominalDiffTime
    a = Micro -> NominalDiffTime
    NominalDiffTime (Int64 -> Micro
    Micro (Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    mjd Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    * Int64
    uPosixDay) Micro -> Micro -> Micro
    forall v. AdditiveGroup v => v -> v -> v
    ^+^ Micro
    dt)