module Data.Astro.Time.Sidereal
(
GreenwichSiderealTime
, LocalSiderealTime
, dhToGST
, dhToLST
, gstToDH
, lstToDH
, hmsToGST
, hmsToLST
, utToGST
, gstToUT
, gstToLST
, lstToGST
, lstToGSTwDC
)
where
import Data.Astro.Types (DecimalHours(..), fromHMS)
import Data.Astro.Time.JulianDate (JulianDate(..), TimeBaseType, numberOfCenturies, splitToDayAndTime)
import Data.Astro.Time.Epoch (j2000)
import Data.Astro.Utils (reduceToZeroRange)
import qualified Data.Astro.Types as C
newtype GreenwichSiderealTime = GST TimeBaseType deriving (Show, Eq)
newtype LocalSiderealTime = LST TimeBaseType deriving (Show, Eq)
dhToGST :: DecimalHours -> GreenwichSiderealTime
dhToGST (DH t) = GST t
dhToLST :: DecimalHours -> LocalSiderealTime
dhToLST (DH t) = LST t
gstToDH :: GreenwichSiderealTime -> DecimalHours
gstToDH (GST t) = DH t
lstToDH :: LocalSiderealTime -> DecimalHours
lstToDH (LST t) = DH t
hmsToGST :: Int -> Int -> TimeBaseType -> GreenwichSiderealTime
hmsToGST h m s = dhToGST $ fromHMS h m s
hmsToLST :: Int -> Int -> TimeBaseType -> LocalSiderealTime
hmsToLST h m s = dhToLST $ fromHMS h m s
utToGST :: JulianDate -> GreenwichSiderealTime
utToGST jd =
let (JD day, JD time) = splitToDayAndTime jd
t = solarSiderealTimesDiff day
time' = reduceToZeroRange 24 $ time*24/siderealDayLength + t
in GST $ time'
gstToUT :: JulianDate -> GreenwichSiderealTime -> JulianDate
gstToUT jd gst =
let (day, time) = dayTime jd gst
t = solarSiderealTimesDiff day
time' = (reduceToZeroRange 24 (time-t)) * siderealDayLength
in JD $ day + time'/24
where dayTime jd (GST gst)
| gst < 0 = (day-1, gst+24)
| gst >= 24 = (day+1, gst-24)
| otherwise = (day, gst)
where (JD day, _) = splitToDayAndTime jd
gstToLST :: C.DecimalDegrees -> GreenwichSiderealTime -> LocalSiderealTime
gstToLST longitude (GST gst) =
let C.DH dhours = C.toDecimalHours longitude
lst = reduceToZeroRange 24 $ gst + dhours
in LST lst
lstToGST :: C.DecimalDegrees -> LocalSiderealTime -> GreenwichSiderealTime
lstToGST longitude (LST lst) =
let C.DH dhours = C.toDecimalHours longitude
gst = reduceToZeroRange 24 $ lst - dhours
in GST gst
lstToGSTwDC :: C.DecimalDegrees -> LocalSiderealTime -> GreenwichSiderealTime
lstToGSTwDC longitude (LST lst) =
let C.DH dhours = C.toDecimalHours longitude
gst = lst - dhours
in GST gst
siderealDayLength :: TimeBaseType
siderealDayLength = hours/24
where C.DH hours = fromHMS 23 56 04.0916
solarSiderealTimesDiff :: TimeBaseType -> TimeBaseType
solarSiderealTimesDiff d =
let t = numberOfCenturies j2000 (JD d)
in reduceToZeroRange 24 $ 6.697374558 + 2400.051336*t + 0.000025862*t*t