28

Is there a function in haskell for epoch time in seconds / milliseconds ?

perhaps something similar to java's

System.currentTimeMillis();

edit: as Int or Integer?

Chris Stryczynski
34.8k60 gold badges210 silver badges334 bronze badges
asked Jul 28, 2013 at 15:25

6 Answers 6

37

Yes.

getCurrentTime :: IO UTCTime.

UNIX epoch time could be retrieved as Int like that:

> :m + Data.Time System.Locale Control.Applicative
> epoch_int <- (read <$> formatTime defaultTimeLocale "%s" <$> getCurrentTime) :: IO Int
> epoch_int
1375025861

UPD: as other users noticed, there is much more simple way to do that:

> :m + Data.Time.Clock.POSIX
> round `fmap` getPOSIXTime 
1375040716
it :: Integer
answered Jul 28, 2013 at 15:28
Sign up to request clarification or add additional context in comments.

8 Comments

got the message " Not in scope: `<$>' "
Converting via String? Technically correct, and probably safe, but feels very much messier than the other solutions here...
@jajdoo just import Control.Applicative. Updated the answer
@BenMillwood other solutions, what?
because it is an IO impure operation. You can't say that every getPOSIXTime call returns you the same value.
|
5

Try this:

import Data.Time
import Data.Time.Clock.POSIX
t = getPOSIXTime

It has 6 decimal places of accuracy.

answered Jul 28, 2013 at 15:28

1 Comment

redundant Data.Time import. t is IO POSIXTime, question is about getting an Int.
4

How about:

import Data.Time.Clock.POSIX (getPOSIXTime)
timeNanos, timeMicros, timeMillis :: IO Integer
t mul = round . (mul *) <$> getPOSIXTime
timeNanos = t 1000000000
timeMicros = t 1000000
timeMillis = t 1000
main = do
 tNanos <- timeNanos
 tMicros <- timeMicros
 tMillis <- timeMillis
 print tNanos
 print tMicros
 print tMillis
-- OUT:
-- 1539161680010615122
-- 1539161680010617
-- 1539161680011
answered Dec 30, 2015 at 21:51

3 Comments

This is incredibly wrong! If you run timeInMicros a couple times in ghci, you'll immediately see that returns almost random output! One moment it's 1538705499660488167, shortly after it's 769352750056244969 which is half the size. You cannot make a Rational and then just keep the numerator - that's like saying something takes 5/365 years, so it's 5 years!
(I got the above results using time-1.8.0.2.)
The idea was to take the numerator of smth that is always n % 1, however, back when I wrote this snippet, getPOSIXTime returned seconds.micros, but now it returns seconds.nanos. Anyway, there are probably better ways to do this. For the time being, I've just used round instead of numerator . toRational.
2

There is also the solution discussed in Real World Haskell:

import System.Time
getClockTime >>= (\(TOD sec _) -> return sec)
answered Jul 28, 2013 at 22:20

1 Comment

This uses the older System.Time package which usually ought to be replaced by Data.Time.
2
import Data.Time.Clock.POSIX
f :: Integral b => IO b
f = getCurrentTime >>= pure . (1000*) . utcTimeToPOSIXSeconds >>= pure . round

Round is to get integer which is not actually mandatory...

original answer was without (1000*) - now is fixed

Chris Stryczynski
34.8k60 gold badges210 silver badges334 bronze badges
answered May 19, 2017 at 10:16

3 Comments

From review queue: May I request you to please add some more context around your answer. Code-only answers are difficult to understand. It will help the asker and future readers both if you can add more information in your post.
Execuse me, for so short (and actually not totally right) answer. As for me, I do it in this manner: getCurrentTime >>= pure . (1000*) . utcTimeToPOSIXSeconds >>= pure . round. Both funcs are in Data.Time.Clock.POSIX. This (running in GHCi) returns milliseconds of current time
@Paul-AG should it not be without the 1000* (for seconds)?
-10

This works:

import System.IO.Unsafe
import Data.Time.Clock.POSIX
time = round (unsafePerformIO getPOSIXTime) :: Int

unsafePerformIO extracts time from the IO monad. Rounding to Int then yields the desired result.

UPDATE: In my Haskell web applications, I sometimes use unsafePerformIO to populate HTML checkbox and radio button forms with random numbers and hidden time stamps. Sometimes my text field and textbox forms allow users (players of interactive games) to provide data such as arbitrary numbers and dates. Justin, I trust that you don't think the user-supplied values are safer than the random numbers and time stamps I supply to the forms? And I hope you don't think I meant to imply, "Use things like unsafePerformIO if you don't understand what you're doing."

Web browsers use HTML, CSS and Javascript. You can't "keep it in the IO monad", and the browsers don't perform more or less safely depending on how the values they receive came out of Haskell monads.

Justin, for the benefit of everyone who reads this page, I ask you to reconsider and say if you still think I "really shouldn't be using unsafePerformIO this way"? My mind is open. I just don't have a clue as to what, if anything, I might be doing wrong in my work, or why readers should be discouraged from learning from me by the two down votes.

P.S. I've heard that one shouldn't say #@!% in front of the children, or in mixed company. Did I publish the "U" word where newbies might see it? Heaven forbid! -DS

answered Jun 8, 2014 at 20:19

3 Comments

You really shouldn't be using unsafePerformIO this way. It's mostly useful for calling functions that you know are pure using FFI. See this SO thread for more info. If you're doing IO, keep it in the IO monad and your program will be safer to use and extend. Only use things like unsafePerformIO if you really understand what you're doing.
My comment is in the update, above. It wouldn't fit here
These are just crazy ways to use unsafePerformIO. Broadly speaking, you shouldn't use unsafePerformIO to perform that sort of IO. Yes, it's fine (in my book) to use it to grab some random numbers for a Las Vegas algorithm like Quickselect (but not for a Monte Carlo one), and it's fine to use it to allow a concurrent algorithm to implement a pure function (although I'm pretty sure there are higher-level functions to do that a little more nicely, though still dangerously), and it's certainly fine for (pure) FFI stuff, but these are not the sorts of things you're doing.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.