module Data.Astro.Time.Conv
(
zonedTimeToLCT
, zonedTimeToLCD
, lctToZonedTime
)
where
import Data.Time.LocalTime (ZonedTime(..), LocalTime(..)
, TimeOfDay(..), TimeZone(..)
, minutesToTimeZone)
import Data.Time.Calendar (toGregorian, fromGregorian)
import Data.Astro.Types(DecimalHours(..))
import Data.Astro.Utils (fromFixed)
import Data.Astro.Time.JulianDate (JulianDate(..)
, LocalCivilTime(..)
, LocalCivilDate(..)
, fromYMDHMS, toYMDHMS
, lctFromYMDHMS, lcdFromYMD
, lctToYMDHMS)
timeZoneToDH :: TimeZone -> DecimalHours
timeZoneToDH :: TimeZone -> DecimalHours
timeZoneToDH TimeZone
tz = Double -> DecimalHours
DH Double
hours
where toMinutes :: TimeZone -> Double
toMinutes = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Double) -> (TimeZone -> Int) -> TimeZone -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeZone -> Int
timeZoneMinutes
hours :: Double
hours = (TimeZone -> Double
toMinutes TimeZone
tz) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
60.0
zonedTimeToLCT :: ZonedTime -> LocalCivilTime
zonedTimeToLCT :: ZonedTime -> LocalCivilTime
zonedTimeToLCT ZonedTime
zonedTime = DecimalHours
-> Integer -> Int -> Int -> Int -> Int -> Double -> LocalCivilTime
lctFromYMDHMS DecimalHours
tz Integer
y Int
m Int
d Int
hours Int
mins (Fixed E12 -> Double
forall a b. (Fractional a, HasResolution b) => Fixed b -> a
fromFixed Fixed E12
secs)
where tz :: DecimalHours
tz = TimeZone -> DecimalHours
timeZoneToDH (ZonedTime -> TimeZone
zonedTimeZone ZonedTime
zonedTime)
lt :: LocalTime
lt = ZonedTime -> LocalTime
zonedTimeToLocalTime ZonedTime
zonedTime
(Integer
y, Int
m, Int
d) = Day -> (Integer, Int, Int)
toGregorian (LocalTime -> Day
localDay LocalTime
lt)
TimeOfDay Int
hours Int
mins Fixed E12
secs = LocalTime -> TimeOfDay
localTimeOfDay LocalTime
lt
zonedTimeToLCD :: ZonedTime -> LocalCivilDate
zonedTimeToLCD :: ZonedTime -> LocalCivilDate
zonedTimeToLCD ZonedTime
zonedTime = DecimalHours -> Integer -> Int -> Int -> LocalCivilDate
lcdFromYMD DecimalHours
tz Integer
y Int
m Int
d
where tz :: DecimalHours
tz = TimeZone -> DecimalHours
timeZoneToDH (ZonedTime -> TimeZone
zonedTimeZone ZonedTime
zonedTime)
lt :: LocalTime
lt = ZonedTime -> LocalTime
zonedTimeToLocalTime ZonedTime
zonedTime
(Integer
y, Int
m, Int
d) = Day -> (Integer, Int, Int)
toGregorian (LocalTime -> Day
localDay LocalTime
lt)
dhToTimeZone :: DecimalHours -> TimeZone
dhToTimeZone :: DecimalHours -> TimeZone
dhToTimeZone (DH Double
hours) = Int -> TimeZone
minutesToTimeZone Int
minutes
where minutes :: Int
minutes = Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (Double
60Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
hours)
lctToZonedTime :: LocalCivilTime -> ZonedTime
lctToZonedTime :: LocalCivilTime -> ZonedTime
lctToZonedTime LocalCivilTime
lct = ZonedTime :: LocalTime -> TimeZone -> ZonedTime
ZonedTime { zonedTimeToLocalTime :: LocalTime
zonedTimeToLocalTime = LocalTime
lt, zonedTimeZone :: TimeZone
zonedTimeZone = TimeZone
tz }
where tz :: TimeZone
tz = DecimalHours -> TimeZone
dhToTimeZone (DecimalHours -> TimeZone) -> DecimalHours -> TimeZone
forall a b. (a -> b) -> a -> b
$ LocalCivilTime -> DecimalHours
lctTimeZone LocalCivilTime
lct
(Integer
y, Int
m, Int
d, Int
hours, Int
mins, Double
secs) = LocalCivilTime -> (Integer, Int, Int, Int, Int, Double)
lctToYMDHMS LocalCivilTime
lct
day :: Day
day = Integer -> Int -> Int -> Day
fromGregorian Integer
y Int
m Int
d
time :: TimeOfDay
time = Int -> Int -> Fixed E12 -> TimeOfDay
TimeOfDay Int
hours Int
mins (Double -> Fixed E12
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
secs)
lt :: LocalTime
lt = LocalTime :: Day -> TimeOfDay -> LocalTime
LocalTime { localDay :: Day
localDay = Day
day, localTimeOfDay :: TimeOfDay
localTimeOfDay = TimeOfDay
time }