aboutsummaryrefslogtreecommitdiff
path: root/lib/GTFS.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/GTFS.hs')
-rw-r--r--lib/GTFS.hs34
1 files changed, 27 insertions, 7 deletions
diff --git a/lib/GTFS.hs b/lib/GTFS.hs
index 9eed8b5..f5c2018 100644
--- a/lib/GTFS.hs
+++ b/lib/GTFS.hs
@@ -13,6 +13,7 @@
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- | All kinds of stuff that has to deal with GTFS directly
-- (i.e. parsing, querying, Aeson instances, etc.)
@@ -36,7 +37,7 @@ import Data.Kind (Type)
import Data.Maybe (fromJust, fromMaybe)
import Data.Text (Text)
import Data.Time (TimeZone (timeZoneMinutes),
- UTCTime (utctDay),
+ UTCTime (..),
dayOfWeek, getCurrentTime)
import Data.Time.Calendar (Day, DayOfWeek (..))
import Data.Time.Calendar.MonthDay (monthAndDayToDayOfYearValid)
@@ -70,6 +71,7 @@ import qualified Data.Text as T
import Data.Time.LocalTime.TimeZone.Olson (getTimeZoneSeriesFromOlsonFile)
import Data.Time.LocalTime.TimeZone.Series (TimeZoneSeries,
timeZoneFromSeries)
+import GHC.Float (int2Double)
-- | for some reason this doesn't exist already in cassava
@@ -100,13 +102,31 @@ instance ToJSON Time where
toJSON (Time seconds _ tzname) =
A.object [ "seconds" A..= seconds, "timezone" A..= tzname ]
--- | converts a value of Time to seconds since midnight in UTC. Itself needs
--- a UTCTime to resolve timezone changes, and the timezone info contained in
--- the GTFS agency
-toSeconds :: Time -> TimeZoneSeries -> UTCTime -> Int
-toSeconds (Time seconds _ _) tzseries reftime =
- seconds - timeZoneMinutes timezone * 60
+-- | a type for all timetable values lacking context
+-- confusingly, usually displayed as minutes
+newtype Seconds = Seconds { unSeconds :: Int }
+ deriving newtype
+ ( Num, ToJSON, FromJSON, Eq, Ord, FromHttpApiData
+ , Read, ToSchema )
+
+instance Show Seconds where
+ show (Seconds s) =
+ if s > 0 then "+"+|s `div` 60|+""
+ else show (s `div` 60)
+
+seconds2Double :: Seconds -> Double
+seconds2Double = int2Double . unSeconds
+
+-- | converts a value of Time to seconds since midnight in UTC, using the
+-- timezone that was valid in the timezone series on the given reference day
+-- at the given number of seconds since midnight (note that this may lead to
+-- strange effects for timezone changes not taking place at midnight)
+toSeconds :: Time -> TimeZoneSeries -> Day -> Seconds
+toSeconds (Time seconds _ _) tzseries refday =
+ Seconds $ seconds - timeZoneMinutes timezone * 60
where timezone = timeZoneFromSeries tzseries reftime
+ reftime = UTCTime refday (fromInteger $ toInteger seconds)
+
-- | Times in GTFS are given without timezone info, which is handled
-- seperately (as an attribute of the stop / the agency). We attach that information