packages feed

horizon (empty) → 0.1.0

raw patch · 5 files changed

+198/−0 lines, 5 filesdep +AC-Angledep +basedep +timesetup-changed

Dependencies added: AC-Angle, base, time

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2015, Joel Stanley++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Joel Stanley nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.org view
@@ -0,0 +1,11 @@+* Welcome!++  This package contains a Haskell module for computing approximate sunrise and+  sunset UTC times from latitude and longitude.++  Note that approximations are provided in UTC time only, no additional support+  for time zones is implemented.++  This module has only been lightly tested, and produces values close to those+  found at http://aa.usno.navy.mil/data/docs/RS_OneYear.php.+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ horizon.cabal view
@@ -0,0 +1,31 @@+name:                horizon+version:             0.1.0+synopsis:            Sunrise and sunset UTC approximations from latitude and longitude coordinates+description:         Provides a basic implementation of the sunrise and sunset equations from <https://en.wikipedia.org/wiki/Sunrise_equation this wikipedia page>.+license:             BSD3+license-file:        LICENSE+author:              Joel Stanley+maintainer:          intractable@gmail.com+category:            Data+build-type:          Simple+extra-source-files:  README.org+cabal-version:       >=1.10+stability:           provisional+homepage:            https://github.com/intractable/horizon+bug-reports:         https://github.com/intractable/horizon/issues+Package-url:         http://hackage.haskell.org/package/horizon+tested-with:         GHC == 7.8.3                        ++library+  exposed-modules:     Data.Time.Horizon+  -- other-modules:+  -- other-extensions:+  build-depends:       base >=4.7      && < 4.8,+                       time >= 1.4.2   && < 1.5,+                       AC-Angle >= 1.0 && < 2.0+  hs-source-dirs:      src+  default-language:    Haskell2010++source-repository head+    type:       git+    location:   https://github.com/intractable/horizon.git
+ src/Data/Time/Horizon.hs view
@@ -0,0 +1,124 @@+{-# LANGUAGE ViewPatterns #-}++{-+  Module     : Data.Time.Horizon+  License    : BSD3+  Copyright  : (C) 2015 Joel Stanley+  Maintainer : Joel Stanley <intractable@gmail.com>+  Stability  : provisional+  +  Provides approximate sunrise and sunset times in UTC from latitude and +  longitude coordinates.++  See https://en.wikipedia.org/wiki/Sunrise_equation.+  See http://aa.usno.navy.mil/data/docs/RS_OneYear.php.++-}++module Data.Time.Horizon+  ( LatitudeNorth+  , LongitudeWest+  , sunrise+  , sunset+  )+  where++import Data.Angle+import Data.Fixed+import Data.Time++type LatitudeNorth = Double +type LongitudeWest = Double++-- | Returns an approximated UTC time of the sunrise on the given UTC day at the given location.+sunrise :: Day -> LongitudeWest -> LatitudeNorth -> UTCTime+sunrise d lw ln = mkUTC d . jdToSeconds $ sunrise' d lw ln++-- | Returns an approximated UTC time of the sunset on the given UTC day at the given location.+sunset :: Day -> LongitudeWest -> LatitudeNorth -> UTCTime+sunset d lw ln = mkUTC d .  jdToSeconds $ sunset' d lw ln++-- | Approximate the Julian date of the sunrise on the given UTC day at the given location.+sunrise' :: Day -> LongitudeWest -> LatitudeNorth -> Double+sunrise' d lw ln = jtransit - (jset - jtransit)+  where+    u        = mkUTC d 0+    jtransit = solarTransit u lw+    jset     = sunset' d lw ln++-- | Approximate the Julian date of the sunset on the given UTC day at the given location.+sunset' :: Day -> LongitudeWest -> LatitudeNorth -> Double+sunset' d lw ln =+  2451545.0009 + ((w0 + lw) / 360) + n + 0.0053 * sine m - 0.0069 * sine (2 * lambda)+  where+    u          = mkUTC d 0+    Degrees w0 = omega0 u lw ln+    n          = fromIntegral (julianCycle u lw :: Integer)+    m          = solarMeanAnomaly u lw+    lambda     = eclipticLongitude u lw++toJD :: RealFrac a => UTCTime -> a+toJD = (+2400000.5) . toMJD+  where+    toMJD (UTCTime (fromIntegral . toModifiedJulianDay -> d) (toRational -> dt)) =+      fromRational (d + dt / 86401)++jdToSeconds :: (RealFrac a, Integral b) => a -> b+jdToSeconds jd = floor (dayFrac * 86401)+  where+    dayFrac = mjd - fromIntegral (floor mjd :: Integer)+    mjd     = jd - 2400000.5++julianCycle :: Integral a => UTCTime -> LongitudeWest -> a+julianCycle u lw = n+  where+    n     = floor (nstar + 0.5)+    nstar = jdate - 2451545.0009 - (lw / 360)+    jdate = toJD u++approxSolarNoon :: UTCTime -> LongitudeWest -> Double+approxSolarNoon u lw = jstar+  where+    jstar = 2451545.0009 + lw / 360 + fromIntegral (julianCycle u lw :: Int)++solarMeanAnomaly :: UTCTime -> LongitudeWest -> Degrees Double+solarMeanAnomaly u lw = Degrees m+  where+    m = (357.5291 + 0.98560028 * (approxSolarNoon u lw - 2451545)) `mod'` 360++equationOfCenter :: UTCTime -> LongitudeWest -> Double+equationOfCenter u lw = c+  where+    c = 1.9148 * sine m + 0.0200 * sine (2 * m) + 0.0003 * sine (3 * m)+    m = solarMeanAnomaly u lw++eclipticLongitude :: UTCTime -> LongitudeWest -> Degrees Double+eclipticLongitude u lw = Degrees lambda+  where+    lambda = (m + 102.9372 + c + 180) `mod'` 360+    Degrees m = solarMeanAnomaly u lw+    c         = equationOfCenter u lw++solarTransit :: UTCTime -> LongitudeWest -> Double+solarTransit u lw = jtransit+  where+    jtransit = jstar + 0.0053 * sine m - 0.0069 * sine (2 * lambda)+    jstar    = approxSolarNoon u lw+    m        = solarMeanAnomaly u lw+    lambda   = eclipticLongitude u lw++declination :: UTCTime -> LongitudeWest -> Degrees Double+declination u lw = arcsine (sine lambda * sine (Degrees 23.45))+  where+    lambda = eclipticLongitude u lw++omega0 :: UTCTime -> LongitudeWest -> LatitudeNorth -> Degrees Double+omega0 u lw ln = arccosine (num / denom)+  where+    num    = sine (Degrees (-0.83)) - sine phi * sine gamma'+    denom  = cosine phi * cosine gamma'+    phi    = Degrees ln+    gamma' = declination u lw++mkUTC :: Day -> Integer -> UTCTime+mkUTC d = UTCTime d . secondsToDiffTime