1
syncClockTime :: TimeZone -> UTCTime -> Pico -> Pico
syncClockTime zone time secondTo = do
    let (TimeOfDay hour minute secondFrom) = localTimeOfDay $ utcToLocalTime zone time
    if secondTo > secondFrom then
        secondTo - secondFrom
    else
        60 + secondTo - secondFrom

I have a couple of questions related to the above code

  1. is there a way to directly extract the seconds secondFrom from the UTCTime without converting it to local time and without specifying a time zone? (if yes: how? if no: why?)
  2. How to actually make the running thread/task to asynchronously sleep for the above found number of seconds?
  • What do you mean by "asynchronously sleep"? – melpomene Dec 10 '17 at 11:11
  • Why is there a `do` in the `syncClockTime`? – Willem Van Onsem Dec 10 '17 at 11:11
  • I don't know F# or C#. – melpomene Dec 10 '17 at 11:18
  • So ... synchronous sleep? That's `threadDelay`. – melpomene Dec 10 '17 at 11:21
  • This question looks like a duplicate of https://stackoverflow.com/questions/13482958/haskell-convert-utctime-to-seconds-and-milliseconds and https://stackoverflow.com/questions/35477808/haskell-create-thread-write-to-screen-sleep-thread-write-something-else-to, so it's probably too broad. – melpomene Dec 10 '17 at 11:22
  • `UTCTime` doesn't have a separate seconds component. It stores a day number and the number of picoseconds since midnight. – melpomene Dec 10 '17 at 11:55
  • @user1892538: `do` has *nothing* to do with `if`-`then`-`else`. `if`-`then`-`else` in fact just maps on the `ifThenElse :: Bool -> a -> a -> a` function. `do` is used as syntactical sugar for a monad (e.g. `IO` monad). – Willem Van Onsem Dec 10 '17 at 12:15

1 Answers1

2

Question 2 is simple: you can make your Haskell process sleep for a specified number of microseconds using delay.

If I understand your Question 1, you want to be able to specify, say 30 seconds, and wait until the next time the system clock is 30 seconds past the minute. So if you call your function at 13:23:27 it will wait 3 seconds until 13:23:30, but if you called it at 13:23:33 then it will wait 57 seconds until 13:24:30.

That is a matter of doing arithmetic on the number of seconds. I would suggest you take the current Posix time using getPOSIXTime. This returns a NominalDiffTime, which is an instance of Real and RealFrac, so normal arithmetic works fine. The code you want is:

t <- getPOSIXTime
let secs = t - fromIntegral (floor (t/60) * 60)

Once you have the number of seconds past the minute you can figure out how long to wait until your target time.

Paul Johnson
  • 17,438
  • 3
  • 42
  • 59
  • Not sure about the distinction you are making between sync and async, but if you only have one thread then "delay" will sleep your entire process. I don't know about .Net threads, but Haskell threads are indeed very light. – Paul Johnson Dec 10 '17 at 14:56
  • @user1892538: "mod" only works with integral types. The formula I gave does the equivalent of "mod", but with fractional types. – Paul Johnson Dec 10 '17 at 16:36