2011-12-20 15 views
10

私はローカルタイムゾーンの次の分の開始まで眠るコードを書こうとしていますが、そうするのが非常に困難です。 timeライブラリは常に私の弱点の1つであり、私はこれを行う簡単な方法がいくつかあると仮定しています。次の分の開始まで眠る

新しいTimeOfDayを計算すると思っていましたが、23:59から00:00までは処理できず、夏時間の切り替えに非常に混乱することでしょう。

ハンドリングの閏秒も素晴らしいボーナスになります。

Control.Concurrent.threadDelayを使って睡眠をするのは、私にとって最も簡単な方法のように思えるので、次のような質問があります。次の分が始まるまでのマイクロ秒数はどうすればわかりますか? DiffTimeおよびNominalDiffTimeは、これを達成するための完全に許容可能な方法です。

+0

現在の時刻の秒のコンポーネントを取得してから60秒間スリープできますか?飛躍的に離れていて、合理的にうまくいくはずです。どのくらい正確に起床したいですか? –

+0

完全に手作業で計算しなくても実際にそれを行う方法が他にない場合はうまくいくでしょうが、同じデータを得ることができる精度を失うのは残念です。しかし、それほど大きな問題ではない。 2分遅れでも問題ありませんが、次の分が始まる前に目を覚まさないようにしたいと思います。エラーは次の分だけ修正されます。確かに、うるう秒はあまり一般的ではありません。 – ehird

+0

うーん、 'UTCTime'のドキュメンテーションは、うるう秒が' getCurrentTime'のような測定アクションによって処理されないことを暗示しているようです。秒フィールドは実際にはピコ秒の精度で与えられるので、私が望むことができる最高の精度が得られます。私はそれを試してみましょう。 – ehird

答えて

10

私はこれがあなたの後のコメントを与えたいとは思えないかもしれないと心配しています。私はこれがうるう年、タイムゾーンの変更、および日の変更を許容すると思うが、うるう秒は許さない。

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" 
+0

結論として、私は60歳以上の睡眠をサポートするために、これに実質的に類似したものを使用してしまいました。私は 'delta ' - mod'(utctDayTime t)delta'を使って、それをマイクロ秒に変換しました。ありがとう! – ehird

+0

threadDelayの値がmaxBound :: Intより小さい限り、小さな時間間隔で動作する可能性があります – Jonke

2

多分これはあなたを助けるでしょう:PLEAC-Haskell: Dates and Times

次の分の開始時刻を作成できる現在の分を得ることができます。次に、睡眠時間としての違いを取る。

+0

私は現在の分を得る方法を知っていますが、日の変更、年の変更、タイムゾーンの変更などに依存するため、次の分の開始はそれよりもはるかに手間がかかります。分→時→日→月→年をカスケードして夏時間を無視できます非常に不便かもしれません...)、それは表現するのはかなり簡単な操作でなければならない何かの手作業のコードでしょう...しかし、それがこれを行う唯一の方法であるということになるかもしれません。 (その場合、より良いタイムライブラリが必要です。) – ehird

+0

ああ、私はうるう年を手動で処理する必要があります。ああ。 – ehird

+0

ああ、今私はあなたの特別な時代の問題を理解しています... しかし、 "11:60:00"(次の開始)と "11:59:42"(現在の時間)は正しく計算されていますか?したがって、ライブラリの解釈/差異の計算に依存します(11:60:00が12:00:00などと解釈されればすべて問題ありません)。 – user905686

1

私は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を返します。これは一般的にはうまくいくと思います。 timeToTimeOfDayの代わりにutcToLocalTimeOfDayを使用してタイムゾーンに固有のものを管理できますが、その後、曜日のオフセットを管理するために余分な作業をする必要があります。

関連する問題