Last active
April 4, 2024 16:09
-
-
Save friedbrice/f9566173436e1697eba4912047a369cd to your computer and use it in GitHub Desktop.
Haskell Time Crib Sheet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- ghcid -c'stack repl --resolver nightly --package time' haskell-time.hs --allow-eval | |
---- | |
-- # Haskell Time Crib Sheet | |
---- | |
-- Excellent sources for this small guide include: | |
-- | |
-- * https://two-wrongs.com/haskell-time-library-tutorial.html | |
-- * https://williamyaoh.com/posts/2019-09-16-time-cheatsheet.html | |
-- * https://wiki.haskell.org/Time | |
-- * https://hackage.haskell.org/package/time-1.10/docs/Data-Time.html | |
{-# LANGUAGE DisambiguateRecordFields, NamedFieldPuns #-} | |
import Control.Applicative ((<|>)) | |
import Data.Fixed (Pico) | |
import qualified Data.Time as T | |
import qualified Data.Time.Format.ISO8601 as T | |
(formatShow, iso8601Format, formatParseM) | |
---- | |
-- ## Basics | |
-- ### Get the current UTC time | |
getCurrentTime :: IO T.UTCTime | |
getCurrentTime = T.getCurrentTime | |
-- $> getCurrentTime | |
-- ### Print UTC time as ISO-8601 | |
printIso8601 :: T.UTCTime -> String | |
printIso8601 utct = T.formatShow T.iso8601Format utct | |
-- $> printIso8601 <$> getCurrentTime | |
-- ### Parse UTC time from ISO-8601 | |
parseUtcIso8601 :: String -> Maybe T.UTCTime | |
parseUtcIso8601 raw = | |
parseNoOffset raw <|> parseWithOffset raw | |
where | |
parseNoOffset = | |
T.formatParseM T.iso8601Format | |
parseWithOffset = | |
fmap T.zonedTimeToUTC . T.formatParseM T.iso8601Format | |
-- $> parseUtcIso8601 "2012-01-23T00:00:00Z" | |
-- $> parseUtcIso8601 "2012-01-23T00:00:00+00:00" | |
-- $> parseUtcIso8601 "2012-01-23T00:00:00-07:00" | |
---- | |
-- ## Manipulation | |
-- ### Add (or subtract) seconds (or minutes or hours) to UTC time | |
addSeconds :: Integer -> T.UTCTime -> T.UTCTime | |
addSeconds n utct = T.addUTCTime (fromInteger n) utct | |
-- $> addSeconds (60 * 60 * 2) <$> getCurrentTime | |
-- ### Add (or subtract) days (or weeks) to UTC time | |
addDays :: Integer -> T.UTCTime -> T.UTCTime | |
addDays n utct = T.addUTCTime (fromInteger n * T.nominalDay) utct | |
-- $> addDays (-1 * 7 * 2) <$> getCurrentTime | |
-- ### Add (or subtract) months (or years) to UTC time | |
addMonths :: Integer -> T.UTCTime -> T.UTCTime | |
addMonths n utct = | |
let | |
[email protected]{ localDay } = T.utcToLocalTime T.utc utct | |
localDay' = T.addGregorianMonthsClip n localDay | |
in | |
T.localTimeToUTC T.utc lt{ T.localDay = localDay' } | |
-- $> addMonths (-2) <$> getCurrentTime | |
---- | |
-- ## Local Time | |
-- ### Get local date | |
getLocalDate :: T.TimeZone -> T.UTCTime -> (Integer, Int, Int) | |
getLocalDate tz utct = | |
let | |
T.LocalTime{ localDay } = T.utcToLocalTime tz utct | |
in | |
T.toGregorian localDay | |
-- $> getLocalDate (read "PDT") <$> getCurrentTime | |
-- ### Get local time | |
getLocalTime :: T.TimeZone -> T.UTCTime -> (Int, Int, Pico) | |
getLocalTime tz utct = | |
let | |
T.LocalTime{ localTimeOfDay } = T.utcToLocalTime tz utct | |
T.TimeOfDay{ todHour, todMin, todSec } = localTimeOfDay | |
in | |
(todHour, todMin, todSec) | |
-- $> getLocalTime (read "PDT") <$> getCurrentTime | |
-- ### Get local day of week | |
getLocalDayOfWeek :: T.TimeZone -> T.UTCTime -> T.DayOfWeek | |
getLocalDayOfWeek tz utct = | |
let | |
T.LocalTime{ localDay } = T.utcToLocalTime tz utct | |
in | |
T.dayOfWeek localDay | |
-- $> getLocalDayOfWeek (read "PDT") <$> getCurrentTime |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment