1{-# OPTIONS -fno-warn-orphans #-}
2module Data.Time.LocalTime.Internal.LocalTime
3(
4    -- * Local Time
5    LocalTime(..),
6
7    addLocalTime,diffLocalTime,
8
9    -- converting UTC and UT1 times to LocalTime
10    utcToLocalTime,localTimeToUTC,ut1ToLocalTime,localTimeToUT1,
11) where
12
13
14
15import Control.DeepSeq
16import Data.Typeable
17import Data.Data
18import Data.Time.Calendar.Days
19import Data.Time.Calendar.Gregorian
20import Data.Time.Clock.Internal.NominalDiffTime
21import Data.Time.Clock.Internal.UniversalTime
22import Data.Time.Clock.Internal.UTCDiff
23import Data.Time.Clock.Internal.UTCTime
24import Data.Time.LocalTime.Internal.TimeOfDay
25import Data.Time.LocalTime.Internal.TimeZone
26
27
28-- | A simple day and time aggregate, where the day is of the specified parameter,
29-- and the time is a TimeOfDay.
30-- Conversion of this (as local civil time) to UTC depends on the time zone.
31-- Conversion of this (as local mean time) to UT1 depends on the longitude.
32data LocalTime = LocalTime {
33    localDay    :: Day,
34    localTimeOfDay   :: TimeOfDay
35} deriving (Eq,Ord,Data, Typeable)
36
37instance NFData LocalTime where
38    rnf (LocalTime d t) = rnf d `seq` rnf t `seq` ()
39
40instance Show LocalTime where
41    show (LocalTime d t) = (showGregorian d) ++ " " ++ (show t)
42
43-- | addLocalTime a b = a + b
44addLocalTime :: NominalDiffTime -> LocalTime -> LocalTime
45addLocalTime x = utcToLocalTime utc . addUTCTime x . localTimeToUTC utc
46
47-- | diffLocalTime a b = a - b
48diffLocalTime :: LocalTime -> LocalTime -> NominalDiffTime
49diffLocalTime a b = diffUTCTime (localTimeToUTC utc a) (localTimeToUTC utc b)
50
51-- | Get the local time of a UTC time in a time zone.
52utcToLocalTime :: TimeZone -> UTCTime -> LocalTime
53utcToLocalTime tz (UTCTime day dt) = LocalTime (addDays i day) tod where
54    (i,tod) = utcToLocalTimeOfDay tz (timeToTimeOfDay dt)
55
56-- | Get the UTC time of a local time in a time zone.
57localTimeToUTC :: TimeZone -> LocalTime -> UTCTime
58localTimeToUTC tz (LocalTime day tod) = UTCTime (addDays i day) (timeOfDayToTime todUTC) where
59    (i,todUTC) = localToUTCTimeOfDay tz tod
60
61-- | Get the local time of a UT1 time on a particular meridian (in degrees, positive is East).
62ut1ToLocalTime :: Rational -> UniversalTime -> LocalTime
63ut1ToLocalTime long (ModJulianDate date) = LocalTime (ModifiedJulianDay localMJD) (dayFractionToTimeOfDay localToDOffset) where
64    localTime = date + long / 360 :: Rational
65    localMJD = floor localTime
66    localToDOffset = localTime - (fromIntegral localMJD)
67
68-- | Get the UT1 time of a local time on a particular meridian (in degrees, positive is East).
69localTimeToUT1 :: Rational -> LocalTime -> UniversalTime
70localTimeToUT1 long (LocalTime (ModifiedJulianDay localMJD) tod) = ModJulianDate ((fromIntegral localMJD) + (timeOfDayToDayFraction tod) - (long / 360))
71
72-- orphan instance
73instance Show UniversalTime where
74    show t = show (ut1ToLocalTime 0 t)
75