2011-12-20 29 views
10

Tôi đang cố gắng viết một số mã để ngủ cho đến khi bắt đầu phút tiếp theo trong múi giờ địa phương, nhưng đang gặp khó khăn lớn khi làm như vậy. Thư viện time luôn là một trong những điểm yếu của tôi, vì vậy tôi giả sử có một số cách dễ dàng để thực hiện việc này.Ngủ cho đến khi bắt đầu phút tiếp theo

Tôi nghĩ chỉ cần tính toán TimeOfDay mới, nhưng điều đó sẽ không xử lý 23:59 đến 00:00 và có lẽ sẽ làm những điều rất khó hiểu với thời gian tiết kiệm ánh sáng ban ngày.

Xử lý giây nhảy vọt cũng sẽ là một phần thưởng hấp dẫn.

Sử dụng Control.Concurrent.threadDelay để ngủ có vẻ như phương pháp đơn giản nhất đối với tôi, do đó, một câu hỏi thay thế sẽ là: Làm thế nào tôi có thể nhận được số micro giây cho đến khi bắt đầu phút tiếp theo? DiffTimeNominalDiffTime sẽ là cách hoàn toàn chấp nhận được để đạt được điều này.

+0

Bạn có thể lấy thành phần giây của thời gian hiện tại và sau đó ngủ (60 giây) giây không? Leap-giây ngoài, mà nên làm việc hợp lý tốt. Làm thế nào chính xác bạn muốn thức dậy được? –

+0

Điều đó sẽ hiệu quả nếu không có cách nào khác để thực hiện nó mà không có tính toán thủ công hoàn toàn, nhưng sẽ là một sự xấu hổ để mất đi độ chính xác gia tăng mà tôi có thể nhận được với cùng một dữ liệu. Nó không phải là một thỏa thuận lớn, mặc dù; là một thứ hai hoặc lâu hơn không phải là một vấn đề, nhưng tôi chắc chắn muốn tránh thức dậy * trước * phút tiếp theo bắt đầu - lỗi mà nó tạo ra sẽ chỉ được sửa chữa vào phút tiếp theo. Phải thừa nhận rằng, giây nhảy vọt không phải là rất phổ biến. – ehird

+0

Hmm, tài liệu cho 'UTCTime' dường như ngụ ý rằng các giây nhuận không được xử lý bởi các hành động đo lường như' getCurrentTime', do đó, nó sẽ là một giải pháp có thể chấp nhận được sau tất cả; trường số giây thực sự được đưa ra cho độ chính xác picosecond, vì vậy nó sẽ mang lại độ chính xác cao nhất mà tôi có thể hy vọng. Tôi sẽ thử. – ehird

Trả lời

10

Tôi lo lắng điều này có thể không phải là những gì bạn muốn đưa ra nhận xét sau này của bạn. Tôi nghĩ rằng điều này sẽ chịu đựng những năm nhuận, thay đổi múi giờ, và những thay đổi trong ngày, nhưng không phải là giây nhảy vọt.

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

Khi nó quay ra, tôi đã kết thúc bằng cách sử dụng một cái gì đó đáng kể tương tự như thế này, để hỗ trợ giấc ngủ> 60s; chỉ tôi đã sử dụng delta '- mod' (utctDayTime t) delta' và sau đó chuyển đổi thành micro giây. Cảm ơn! – ehird

+0

Đối với các khoảng thời gian nhỏ có thể hoạt động miễn là giá trị cho luồngDelay nhỏ hơn maxBound :: Int – Jonke

2

Có thể điều này sẽ giúp bạn: PLEAC-Haskell: Dates and Times.

Với sự trợ giúp của nó, bạn sẽ có thể nhận được phút hiện tại mà bạn có thể tạo thời gian bắt đầu phút tiếp theo. Sau đó, chỉ cần có sự khác biệt như thời gian ngủ.

+0

Tôi biết cách lấy phút hiện tại, nhưng nhận được sự bắt đầu của phút tiếp theo là đáng kể hơn, vì nó phụ thuộc vào thay đổi ngày, thay đổi năm, thay đổi múi giờ, v.v. * * có thể * chỉ xếp thứ tự phút → giờ → ngày → tháng → năm và bỏ qua thời gian tiết kiệm ánh sáng ban ngày (sẽ rất bất tiện ...), nhưng đó sẽ là rất nhiều mã hướng dẫn sử dụng cho một thứ cần phải là một hoạt động khá đơn giản để thể hiện ... nó có thể kết thúc là đây là cách duy nhất để làm điều đó. (Trong trường hợp đó chúng ta cần một thư viện thời gian tốt hơn.) – ehird

+0

Ồ, và tôi cũng phải xử lý những năm nhuận thủ công. Ugh. – ehird

+0

Ah, giờ tôi đã hiểu vấn đề của bạn với thời gian đặc biệt ... Nhưng nếu sự khác biệt giữa ví dụ: "11:60:00" (bắt đầu phút tiếp theo) và "11:59:42" (thời gian hiện tại) được tính toán chính xác? Vì vậy, nó phụ thuộc vào việc giải thích các thư viện/tính toán sự khác biệt (nếu 11:60:00 được hiểu là 12:00:00, vv mọi thứ đều ổn). – user905686

1

Tôi không phải chuyên gia về gói time, nhưng làm thế nào về một cái gì đó như thế này:

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 

này sẽ dẫn đến diff :: DiffTime với sự khác biệt đúng trong vài giây; tất cả các ranh giới và năm nhuận phải được tính toán. Tôi không chắc chắn về giây nhảy vọt; bạn có thể cần thêm chúng theo cách thủ công.

Điều này không giải thích cho bất kỳ vùng mang cụ thể theo múi giờ nào, nhưng khi getCurrentTime trả về UTCTime, tôi nghĩ nó sẽ hoạt động bình thường. Bạn có thể thử sử dụng utcToLocalTimeOfDay thay vì timeToTimeOfDay để quản lý công cụ cụ thể theo múi giờ, nhưng sau đó bạn phải thực hiện thêm công việc để quản lý việc bù ngày.

Các vấn đề liên quan