summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@cryptonomic.net>2022-09-15 13:03:47 -0400
committerAndrew Cady <d@cryptonomic.net>2022-09-15 13:03:47 -0400
commit79957e34c8c8e0f3682884a5888b12a6f336f735 (patch)
tree263fcc5b44b7a10e3db4a4bc9f525f814b39c062
parent8b7f519c3ca5a132f21f6afbf8149ad3981d71a0 (diff)
switch away from UTCTime
-rwxr-xr-xcountdown.hs87
1 files changed, 51 insertions, 36 deletions
diff --git a/countdown.hs b/countdown.hs
index 08ca2e2..4d43224 100755
--- a/countdown.hs
+++ b/countdown.hs
@@ -74,37 +74,39 @@ lengthOfDay = 24 * 60 * 60
74ageOfUniverse :: NominalDiffTime 74ageOfUniverse :: NominalDiffTime
75ageOfUniverse = fromIntegral ageOfUniverseInYears * lengthOfYear 75ageOfUniverse = fromIntegral ageOfUniverseInYears * lengthOfYear
76 76
77data CustomEvent = TimeChanged UTCTime deriving Show 77data CustomEvent = TimeChanged ZonedTime deriving Show
78 78
79data St = 79data St =
80 St { _stLastBrickEvent :: Maybe (BrickEvent () CustomEvent) 80 St { _stLastBrickEvent :: Maybe (BrickEvent () CustomEvent)
81 , _stClockTime :: UTCTime 81 , _stClockTime :: LocalTime
82 , _stDisplayTime :: UTCTime 82 , _stDisplayTime :: LocalTime
83 , _stNextEvent :: Maybe UTCTime 83 , _stNextEvent :: Maybe UTCTime
84 } 84 }
85 85
86makeLenses ''St 86makeLenses ''St
87 87
88yearNumber :: ZonedTime -> Integer 88yearNumber :: LocalTime -> Integer
89yearNumber (ZonedTime t _) = y 89yearNumber (LocalTime t _) = y
90 where 90 where
91 (y, _, _) = toGregorian . localDay $ t 91 (y, _, _) = toGregorian t
92 92
93yearStart :: ZonedTime -> ZonedTime 93yearStart :: LocalTime -> LocalTime
94yearStart (ZonedTime t z) = (ZonedTime t' z) 94yearStart (LocalTime d _) = LocalTime d' t'
95 where 95 where
96 t' = LocalTime (fromGregorian y 1 1) (TimeOfDay 0 0 0) 96 d' = fromGregorian y 1 1
97 (y, _, _) = toGregorian . localDay $ t 97 t' = TimeOfDay 0 0 0
98 (y, _, _) = toGregorian d
98 99
99yearEnd :: ZonedTime -> ZonedTime 100yearEnd :: LocalTime -> LocalTime
100yearEnd (ZonedTime t z) = (ZonedTime t' z) 101yearEnd (LocalTime d _) = LocalTime d' t'
101 where 102 where
102 t' = LocalTime (fromGregorian (y + 1) 1 1) (TimeOfDay 0 0 0) 103 d' = fromGregorian (y + 1) 1 1
103 (y, _, _) = toGregorian . localDay $ t 104 t' = TimeOfDay 0 0 0
105 (y, _, _) = toGregorian d
104 106
105 107
106dayNumOfYear :: ZonedTime -> Int 108dayNumOfYear :: LocalTime -> Int
107dayNumOfYear t = snd $ toOrdinalDate $ localDay $ zonedTimeToLocalTime t 109dayNumOfYear = snd . toOrdinalDate . localDay
108 110
109pluralize :: Integral i => i -> String 111pluralize :: Integral i => i -> String
110pluralize 1 = "" 112pluralize 1 = ""
@@ -121,11 +123,11 @@ drawUI st = [a]
121 -- <=> 123 -- <=>
122 (str "\n") 124 (str "\n")
123 <=> 125 <=>
124 (countdownWidget (isSimulatedTime st) $ utcToZonedTime zone $ st ^. stDisplayTime) 126 (countdownWidget (isSimulatedTime st) $ st ^. stDisplayTime)
125 127
126printRemain unit quantity = printf "%d %s%s remain%s" 128printRemain unit quantity = printf "%d %s%s remain%s"
127 129
128countdownWidget :: Bool -> ZonedTime -> Widget n 130countdownWidget :: Bool -> LocalTime -> Widget n
129countdownWidget isSimulated t = 131countdownWidget isSimulated t =
130 (hCenter (borderWithLabel (str $ printf "Current time%s" (if isSimulated then " (SIMULATED)" else "")) $ 132 (hCenter (borderWithLabel (str $ printf "Current time%s" (if isSimulated then " (SIMULATED)" else "")) $
131 padLeftRight 3 $ (str (formatTime defaultTimeLocale "%A, %B %e%n%Y-%m-%d %r" t)))) 133 padLeftRight 3 $ (str (formatTime defaultTimeLocale "%A, %B %e%n%Y-%m-%d %r" t))))
@@ -179,7 +181,7 @@ countdownWidget isSimulated t =
179 numDays = daysInYear t 181 numDays = daysInYear t
180 yearLength = fromIntegral numDays * nominalDay 182 yearLength = fromIntegral numDays * nominalDay
181 -- yearLength = (zonedTimeToLocalTime $ yearEnd t) `diffLocalTime` (zonedTimeToLocalTime $ yearStart t) 183 -- yearLength = (zonedTimeToLocalTime $ yearEnd t) `diffLocalTime` (zonedTimeToLocalTime $ yearStart t)
182 yearElapsed = (zonedTimeToLocalTime t) `diffLocalTime` (zonedTimeToLocalTime $ yearStart t) 184 yearElapsed = t `diffLocalTime` (yearStart t)
183 185
184 daysLeft = numDays - dayNum 186 daysLeft = numDays - dayNum
185 hoursLeft = minutesLeft / 60 187 hoursLeft = minutesLeft / 60
@@ -208,10 +210,10 @@ nextWholeSecond (UTCTime day dayTime) = (UTCTime day dayTime')
208threadDelayUntil :: UTCTime -> UTCTime -> IO () 210threadDelayUntil :: UTCTime -> UTCTime -> IO ()
209threadDelayUntil now t = threadDelay $ microsecondsUntil now t 211threadDelayUntil now t = threadDelay $ microsecondsUntil now t
210 212
211queueNextEvent :: MonadIO m => BChan CustomEvent -> UTCTime -> m () 213queueNextEvent :: MonadIO m => BChan CustomEvent -> ZonedTime -> m ()
212queueNextEvent chan now = liftIO . void . forkIO $ do 214queueNextEvent chan (zonedTimeToUTC -> now) = liftIO . void . forkIO $ do
213 threadDelayUntil now (nextWholeSecond now) 215 threadDelayUntil now (nextWholeSecond now)
214 getCurrentTime >>= writeBChan chan . TimeChanged 216 getZonedTime >>= writeBChan chan . TimeChanged
215 217
216isSimulatedTime :: St -> Bool 218isSimulatedTime :: St -> Bool
217isSimulatedTime st = st ^. stDisplayTime /= st ^. stClockTime 219isSimulatedTime st = st ^. stDisplayTime /= st ^. stClockTime
@@ -220,26 +222,39 @@ handleEvent :: BChan CustomEvent -> St -> BrickEvent () CustomEvent -> EventM ()
220handleEvent chan st e = 222handleEvent chan st e =
221 case e of 223 case e of
222 VtyEvent (V.EvKey V.KEsc []) -> halt st 224 VtyEvent (V.EvKey V.KEsc []) -> halt st
223 VtyEvent (V.EvKey V.KPageUp []) -> cont $ st & stDisplayTime %~ (addUTCTime lengthOfDay) 225 VtyEvent (V.EvKey V.KPageUp []) -> cont $ st & stDisplayTime %~ (addLocalTime lengthOfDay)
224 VtyEvent (V.EvKey V.KPageDown []) -> cont $ st & stDisplayTime %~ (addUTCTime (-lengthOfDay)) 226 VtyEvent (V.EvKey V.KPageDown []) -> cont $ st & stDisplayTime %~ (addLocalTime (-lengthOfDay))
225 VtyEvent (V.EvKey V.KUp []) -> cont $ st & stDisplayTime %~ (addUTCTime (60 * 60)) 227 VtyEvent (V.EvKey V.KUp []) -> cont $ st & stDisplayTime %~ (addLocalTime (60 * 60))
226 VtyEvent (V.EvKey V.KDown []) -> cont $ st & stDisplayTime %~ (addUTCTime (-60 * 60)) 228 VtyEvent (V.EvKey V.KDown []) -> cont $ st & stDisplayTime %~ (addLocalTime (-60 * 60))
227 VtyEvent (V.EvKey V.KRight []) -> cont $ st & stDisplayTime %~ (addUTCTime (60)) 229 VtyEvent (V.EvKey V.KRight []) -> cont $ st & stDisplayTime %~ (addLocalTime (60))
228 VtyEvent (V.EvKey V.KLeft []) -> cont $ st & stDisplayTime %~ (addUTCTime (-60)) 230 VtyEvent (V.EvKey V.KLeft []) -> cont $ st & stDisplayTime %~ (addLocalTime (-60))
229 VtyEvent (V.EvKey V.KRight [MShift]) -> cont $ st & stDisplayTime %~ (addUTCTime (1)) 231 VtyEvent (V.EvKey V.KRight [MShift]) -> cont $ st & stDisplayTime %~ (addLocalTime (1))
230 VtyEvent (V.EvKey V.KLeft [MShift]) -> cont $ st & stDisplayTime %~ (addUTCTime (-1)) 232 VtyEvent (V.EvKey V.KLeft [MShift]) -> cont $ st & stDisplayTime %~ (addLocalTime (-1))
231 VtyEvent (V.EvKey V.KHome []) -> cont $ st & stDisplayTime .~ (st ^. stClockTime) 233 VtyEvent (V.EvKey V.KHome []) -> cont $ st & stDisplayTime .~ (st ^. stClockTime)
234 VtyEvent (V.EvKey V.KHome [MShift]) -> cont $ st & stDisplayTime .~ (newYearsEveNoon $ st ^. stClockTime)
235 VtyEvent (V.EvKey V.KHome [MCtrl]) -> cont $ st & stDisplayTime .~ (newYearsEveLast10 $ st ^. stClockTime)
232 VtyEvent _ -> cont st 236 VtyEvent _ -> cont st
233 AppEvent (TimeChanged now) -> do 237 AppEvent (TimeChanged now) -> do
234 queueNextEvent chan now 238 queueNextEvent chan now
235 let oldTime = st ^. stClockTime 239 let oldTime = st ^. stClockTime
236 cont $ st & stClockTime .~ now & stDisplayTime %~ (addUTCTime (now `diffUTCTime` oldTime)) 240 cont $ st & stClockTime .~ (zonedTimeToLocalTime now) & stDisplayTime %~ (addLocalTime ((zonedTimeToLocalTime now) `diffLocalTime` oldTime))
237 _ -> cont st 241 _ -> cont st
238 where 242 where
239 cont s = do 243 cont s = do
240 continue $ s & stLastBrickEvent .~ (Just e) 244 continue $ s & stLastBrickEvent .~ (Just e)
241 245
242initialState :: UTCTime -> St 246newYearsEveLast10 :: LocalTime -> LocalTime
247newYearsEveLast10 t = addLocalTime (12 * 60 * 60 - 10) $ newYearsEveNoon t
248
249newYearsEveNoon :: LocalTime -> LocalTime
250newYearsEveNoon (LocalTime d (TimeOfDay _ _ s)) = LocalTime d' t
251 where
252 (y, _) = toOrdinalDate d
253 d' = fromOrdinalDate y 366
254 t = TimeOfDay 12 0 s'
255 s' = s `mod'` 1 -- keep the fractional part so we still tick the display on the same schedule
256
257initialState :: LocalTime -> St
243initialState t = 258initialState t =
244 St { _stLastBrickEvent = Nothing 259 St { _stLastBrickEvent = Nothing
245 , _stClockTime = t 260 , _stClockTime = t
@@ -247,8 +262,8 @@ initialState t =
247 , _stNextEvent = Nothing 262 , _stNextEvent = Nothing
248 } 263 }
249 264
250daysInYear :: ZonedTime -> Int 265daysInYear :: LocalTime -> Int
251daysInYear (toGregorian . localDay . zonedTimeToLocalTime -> (y, _, _)) = if isLeapYear y then 366 else 365 266daysInYear (toGregorian . localDay -> (y, _, _)) = if isLeapYear y then 366 else 365
252 267
253theBaseAttr :: A.AttrName 268theBaseAttr :: A.AttrName
254theBaseAttr = A.attrName "theBase" 269theBaseAttr = A.attrName "theBase"
@@ -294,6 +309,6 @@ main = do
294 309
295 let buildVty = V.mkVty V.defaultConfig 310 let buildVty = V.mkVty V.defaultConfig
296 initialVty <- buildVty 311 initialVty <- buildVty
297 now <- getCurrentTime 312 now <- getZonedTime
298 queueNextEvent chan now 313 queueNextEvent chan now
299 void $ customMain initialVty buildVty (Just chan) (theApp chan) (initialState now) 314 void $ customMain initialVty buildVty (Just chan) (theApp chan) (initialState $ zonedTimeToLocalTime now)