Сон до начала следующей минуты

Я пытаюсь написать некоторый код для сна до начала следующей минуты в локальном часовом поясе, но мне очень трудно это делать. Библиотека 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 для управления конкретными событиями часового пояса, но тогда вам придется выполнять дополнительную работу для управления дневными смещениями.