diff options
Diffstat (limited to 'lib/Postdelay/TimeSpec.hs')
-rw-r--r-- | lib/Postdelay/TimeSpec.hs | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/lib/Postdelay/TimeSpec.hs b/lib/Postdelay/TimeSpec.hs index 8244885..384de4b 100644 --- a/lib/Postdelay/TimeSpec.hs +++ b/lib/Postdelay/TimeSpec.hs | |||
@@ -36,6 +36,13 @@ seconds' = seconds . iso (% Second) (# Second) | |||
36 | utcOffset :: Iso' TimeZone Time | 36 | utcOffset :: Iso' TimeZone Time |
37 | utcOffset = iso ((% Minute) . fromIntegral . timeZoneMinutes) (minutesToTimeZone . round . (# Minute)) | 37 | utcOffset = iso ((% Minute) . fromIntegral . timeZoneMinutes) (minutesToTimeZone . round . (# Minute)) |
38 | 38 | ||
39 | shiftBack :: MonadState LocalTime m => Time -> m a -> m a | ||
40 | shiftBack by mod = join $ shiftBack' <$> get <*> mod <*> get | ||
41 | where | ||
42 | shiftBack' prev ret new | ||
43 | | new < prev = ret <$ (flexDT.seconds' %= (^+^) by) | ||
44 | | otherwise = pure ret | ||
45 | |||
39 | 46 | ||
40 | timeSpec :: forall s m. StringParser s m => m (Endo LocalTime) | 47 | timeSpec :: forall s m. StringParser s m => m (Endo LocalTime) |
41 | timeSpec = label "Relative time specification" $ | 48 | timeSpec = label "Relative time specification" $ |
@@ -44,23 +51,23 @@ timeSpec = label "Relative time specification" $ | |||
44 | , offsets False | 51 | , offsets False |
45 | ] | 52 | ] |
46 | where | 53 | where |
47 | specBase = foldMap toEndo <$> mkGramSepBy spaces [ absDate | 54 | specBase = toEndo <$> mkGramSepBy spaces [ timeOfDay |
48 | , timeOfDay | 55 | , dateSpec |
49 | ] | 56 | ] |
50 | 57 | ||
51 | toEndo :: RWS LocalTime () LocalTime a -> Endo LocalTime | 58 | toEndo :: [RWS LocalTime () LocalTime a] -> Endo LocalTime |
52 | toEndo act = Endo $ \t -> fst $ execRWS act t t | 59 | toEndo acts = Endo $ \t -> fst $ execRWS (sequence acts) t t |
53 | 60 | ||
54 | timeOfDay, absDate :: StringParser s m => m (RWS LocalTime () LocalTime ()) | 61 | timeOfDay, dateSpec :: StringParser s m => m (RWS LocalTime () LocalTime ()) |
55 | timeOfDay = label "Time of day" $ assign time <$> choice | 62 | timeOfDay = label "Time of day" $ shiftBack (1 % Day) . assign time <$> choice |
56 | [ TimeOfDay 0 0 0 <$ string' "midnight" | 63 | [ TimeOfDay 0 0 0 <$ string' "midnight" |
57 | , TimeOfDay 12 0 0 <$ string' "noon" | 64 | , TimeOfDay 12 0 0 <$ string' "noon" |
58 | , TimeOfDay 16 0 0 <$ string' "teatime" | 65 | , TimeOfDay 16 0 0 <$ string' "teatime" |
59 | ] | 66 | ] |
60 | absDate = label "Date" . (fmap . (=<<) . assign $ date) $ choice | 67 | dateSpec = label "Date" $ (date <~) <$> choice |
61 | [ view date <$ string' "today" | 68 | [ view date <$ string' "today" |
62 | , views date succ <$ string' "tomorrow" | 69 | , views date succ <$ string' "tomorrow" |
63 | ] | 70 | ] |
64 | 71 | ||
65 | offsets :: forall s m. StringParser s m | 72 | offsets :: forall s m. StringParser s m |
66 | => Bool -- ^ Require sign on first offset? | 73 | => Bool -- ^ Require sign on first offset? |