timezone-detect- Haskell bindings for the zone-detect C library; plus tz-aware utils.
Safe HaskellNone



Exposes utilities derived from the excellent ZoneDetect library https://github.com/BertoldVdb/ZoneDetect. To use this module, you need to obtain database files from the aforementioned library's server.

Additionally, if you have a local time, latitude and longitude, we use the timezone-series and timezone-olson packages to help determine the equivalent UTC instant to that point in geography and time.

The only relevant binding to ZoneDetect is lookupTimeZoneName, richer information that plays neatly with the notion of TimeZone could be derived, but I didn't have a personal need for that yet.

Functions to open, close, and work with an open database (from a valid file) are provided.



type TimeZoneName = FilePath Source #

Alias for clarity, timezones are path-like strings that follow the IANA conventions documented here: https://data.iana.org/time-zones/tz-link.html and here: https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones

type TimeZoneDatabase = Ptr ZoneDetectInfo Source #

A reference to a timezone database.

openTimeZoneDatabase :: FilePath -> IO TimeZoneDatabase Source #

Open a timezone database file and obtain a pointer to the database, as interpreted by the underlying C code.

closeTimeZoneDatabase :: TimeZoneDatabase -> IO () Source #

Given a pointer to a timezone database, close any allocated resources.

withTimeZoneDatabase :: FilePath -> (TimeZoneDatabase -> IO a) -> IO a Source #

Given a path to a timezone database file, and a computation to run with it, takes care of opening the file, running the computation and then closing it.

lookupTimeZoneName :: MonadFail m => TimeZoneDatabase -> Double -> Double -> m TimeZoneName Source #

Given a timezone database, latitude and longitude, try to determine the timezone name. Follow the instructions in the C library's repository to obtain timezone database files (https://github.com/BertoldVdb/ZoneDetect/tree/05567e367576d7f3efa00083b7661a01e43dc8ca/database) Once in possesion of said files, the lookup looks as follows:

>>> db <- openTimeZoneDatabase "./test/tz_db/timezone21.bin"
>>> let tz = lookupTimeZoneName db 40.7831 (-73.9712) :: Maybe TimeZoneName
Just "America/New_York"
>>> closeTimeZoneDatabase db

An invalid database pointer, or invalid coordinates, will cause the given monad to fail. Note that we follow the original library's pattern of obtaining the TimeZoneDatabase separately (which could prove advantageous in e.g a web server.) If you're doing a one-off lookup, or are okay with the IO cost of opening the DB file, see lookupTimeZoneNameFromFile.

lookupTimeZoneNameFromFile :: FilePath -> Double -> Double -> IO TimeZoneName Source #

Same as lookupTimeZoneName, but takes the path to the database file and only works in IO.

timeAtPointToUTC :: TimeZoneDatabase -> Double -> Double -> LocalTime -> IO UTCTime Source #

Given a timezone database, latitude, longitude and a local reference time, find the UTC Time equivalent of that reference time in the given timezone. The reference time helps determine which offset was in effect, since daylight savings, historical circumstances, political revisions and other circumstances (documented in the olson tz database) may have been in effect at that point in spacetime.

timeAtPointToUTCFromFile :: FilePath -> Double -> Double -> LocalTime -> IO UTCTime Source #

Same as timeAtPointToUTC, but takes the path to the timezone database file and takes care of opening and closing the file.

timeInTimeZoneToUTC :: TimeZoneName -> LocalTime -> IO UTCTime Source #

Given a timezone name (presumably obtained via lookupTimeZoneName,) and a reference time in LocalTime, find the UTC equivalent.