diff --git a/src/System/Cron/Describe.hs b/src/System/Cron/Describe.hs index 4de2b6d..8396de3 100644 --- a/src/System/Cron/Describe.hs +++ b/src/System/Cron/Describe.hs @@ -28,6 +28,7 @@ module System.Cron.Describe defaultOpts , twentyFourHourFormat , twelveHourFormat + , customFormat , verbose , notVerbose , OptionBuilder diff --git a/src/System/Cron/Internal/Describe/Options.hs b/src/System/Cron/Internal/Describe/Options.hs index 209a5b3..6e12de4 100644 --- a/src/System/Cron/Internal/Describe/Options.hs +++ b/src/System/Cron/Internal/Describe/Options.hs @@ -16,6 +16,7 @@ import Data.Default.Class import Data.Semigroup as Semigroup ------------------------------------------------------------------------------- import System.Cron.Internal.Describe.Types +import Data.Time (TimeZone, TimeLocale) ------------------------------------------------------------------------------- @@ -46,6 +47,13 @@ twelveHourFormat :: OptionBuilder twelveHourFormat = Builder (\o -> o {timeFormat = Hour12} ) +-- | Return a builder that sets the options to use a custom time format. +-- This takes in a time zone, a time locale, and a time formatting string defined by: +-- https://hackage.haskell.org/package/time-1.12.2/docs/Data-Time-Format.html#t:FormatTime +customFormat :: TimeZone -> TimeLocale -> String -> OptionBuilder +customFormat z l f = Builder (\o -> o {timeFormat = CustomTimeFormat z l f} ) + + -- | Return a builder that sets the options to be verbose. A verbose description -- doesn't eliminate unnecessary information. The only caveat being that month -- information is only ever displayed if it isn't "*". diff --git a/src/System/Cron/Internal/Describe/Time.hs b/src/System/Cron/Internal/Describe/Time.hs index c13e961..3a91693 100644 --- a/src/System/Cron/Internal/Describe/Time.hs +++ b/src/System/Cron/Internal/Describe/Time.hs @@ -1,20 +1,17 @@ module System.Cron.Internal.Describe.Time where import System.Cron.Internal.Describe.Types +import Data.Time (formatTime, TimeOfDay (TimeOfDay), defaultTimeLocale, TimeLocale, TimeZone, utc, utcToLocalTimeOfDay) newtype Minute = Minute Int newtype Hour = Hour Int format :: TimeFormat -> Minute -> Hour -> String -format t (Minute m) (Hour h) = leftPad (hour t) ++ ":" ++ leftPad m ++ suffix t - where leftPad n - | n < 10 = "0" ++ show n - | otherwise = show n - suffix Hour24 = "" - suffix Hour12 - | h < 12 = " AM" - | otherwise = " PM" - hour Hour24 = h - hour Hour12 - | h > 12 = h `mod` 12 - | otherwise = h +format Hour24 = fmtTime utc defaultTimeLocale "%R" +format Hour12 = fmtTime utc defaultTimeLocale "%I:%M %p" +format (CustomTimeFormat zone locale pattern) = fmtTime zone locale pattern + +fmtTime :: TimeZone -> TimeLocale -> String -> Minute -> Hour -> String +fmtTime zone locale pattern (Minute m) (Hour h) = formatTime locale pattern tod + where + tod = snd . utcToLocalTimeOfDay zone $ TimeOfDay h m 0 \ No newline at end of file diff --git a/src/System/Cron/Internal/Describe/Types.hs b/src/System/Cron/Internal/Describe/Types.hs index 85990b6..68e94bb 100644 --- a/src/System/Cron/Internal/Describe/Types.hs +++ b/src/System/Cron/Internal/Describe/Types.hs @@ -4,6 +4,7 @@ module System.Cron.Internal.Describe.Types where import Data.List (intercalate) import Data.Maybe (catMaybes) +import Data.Time (TimeLocale, TimeZone) data Descriptor = Descriptor { @@ -44,7 +45,7 @@ safeIntToWeekDay n data Verbosity = Verbose | NotVerbose -data TimeFormat = Hour24 | Hour12 +data TimeFormat = Hour24 | Hour12 | CustomTimeFormat TimeZone TimeLocale String data DescribedValue = Concrete String