Сон до начала следующей минуты
Я пытаюсь написать некоторый код для сна до начала следующей минуты в локальном часовом поясе, но мне очень трудно это делать. Библиотека time
всегда была одной из моих слабых сторон, поэтому я предполагаю, что есть простой способ сделать это.
Я подумал о том, чтобы просто вычислить новый TimeOfDay, но это не будет работать с 23:59 до 00:00 и, вероятно, будет очень путать вещи с переход на летнее время.
Обработка секунд прыжка тоже была бы неплохим бонусом.
Использование Control.Concurrent.threadDelay для сна - это самый простой способ для меня, поэтому альтернативный вопрос: как я могу получить количество микросекунд до начала следующей минуты? DiffTime
и NominalDiffTime
были бы вполне приемлемыми способами для достижения этого.
Ответы
Ответ 1
Я беспокоюсь, что это может быть не то, что вы хотите, учитывая ваши более поздние комментарии. Я думаю, что это будет терпеть високосные годы, изменения часовых поясов и дневные изменения, но не прыжки секунд.
import Control.Concurrent (threadDelay)
import Data.Time.Clock
sleepToNextMinute :: IO ()
sleepToNextMinute = do t <- getCurrentTime
let secs = round (realToFrac $ utctDayTime t) `rem` 60
threadDelay $ 1000000 * (60 - secs)
main = do putStrLn "Starting..."
sleepToNextMinute
putStrLn "Minute 1"
sleepToNextMinute
putStrLn "Minute 2"
Ответ 2
Возможно, это поможет вам: PLEAC-Haskell: Даты и время.
С его помощью вы сможете получить текущую минуту, с которой вы можете создать время начала следующей минуты. Тогда просто используйте разницу как время сна.
Ответ 3
Я не эксперт в пакете time
, но как насчет чего-то вроде этого:
import Data.Time -- need Clock and LocalTime
curTime <- getCurrentTime
let curTOD = timeToTimeOfDay $ utctDayTime curTime
last = TimeOfDay (todHour curTOD) (todMin curTOD) 0
diff = timeOfDayToTime last + 60 - utctDayTime curTime
Это приведет к diff :: DiffTime
с правильной разницей в секундах; все границы и високосные годы должны учитываться. Я не уверен в прыжках секунд; вам, вероятно, придется добавить их вручную.
Это не учитывает какое-либо зависание в часовом поясе, но поскольку getCurrentTime
возвращает UTCTime, я думаю, что он будет работать в целом. Вы можете использовать utcToLocalTimeOfDay
вместо timeToTimeOfDay
для управления конкретными событиями часового пояса, но тогда вам придется выполнять дополнительную работу для управления дневными смещениями.