# Converting between AbsoluteTime and Unix time

By trial and error, I've found that the following gives the current Unix time:

AbsoluteTime[] - UPOCH


where UPOCH can be defined in any of the following ways:

UPOCH = Round[AbsoluteTime[{1970,  1,  1,  0,         0, 0}, TimeZone->-14]]
UPOCH = Round[AbsoluteTime[{1969, 12, 31, 10,         0, 0}, TimeZone->0]]
UPOCH = Round[AbsoluteTime[{1970,  1,  1, TimeZone[], 0, 0}]]
UPOCH = 2208963600


Just as you can subtract UPOCH to convert Mathematica's AbsoluteTime to Unix time, you can convert a Unix time to Mathematica's epoch time by adding UPOCH.

My question is why? Why isn't it AbsoluteTime[{1970,1,1, 0,0,0}, TimeZone->0]?

Related question: UNIX time to DateList

UPDATE: Here's what you actually want (thanks to @2012rcampion):

UPOCH = AbsoluteTime[DateObject[{1970, 1, 1, 0, 0, 0}, TimeZone->0]]

• dreeves, I haven't seen you post in a long time! Welcome to the new site. I hope you'll stick around. :-) Mar 23 '15 at 3:54
• Thank you! I take it the cool kids are all here now, as opposed to using the mathematica tag on StackOverflow? Or is the latter still the right place for sufficiently programmy questions? Mar 23 '15 at 4:47
• There are exceptions, e.g. High Performance Mark, but just about everyone with skill is over here now. The subject scope is quite broad; for the most part if it is Mathematica related it is accepted. Some questions that mention Mathematica but otherwise have little to do with it may be migrated to Mathematics, Cross Validated, or Signal Processing. Mar 23 '15 at 6:42
• Your 4 examples for calculating UPOCH give different results: 2208934800, 2208934800, 2208992400 and 2208963600. Is this correct?
– shrx
Mar 23 '15 at 9:07
• Oh, interesting, they all give 2208963600 in Mathematica 10 for me. So this is a new mystery! With an explicit TimeZone given I'd have thought that AbsoluteTime would give consistent results on different systems. Mar 23 '15 at 17:32

{1970, 1, 1, 0, 0, 0} is shorthand for a DateObject, namely this one:

DateObject[{1970, 1, 1, 0, 0, 0}]


This represents January 1, 1970 in your current time zone. The origin of UNIX time is January 1, 1970 UTC:

DateObject[{1970, 1, 1, 0, 0, 0}, TimeZone -> 0]


Note now that the returned DateObject displays with the time zone GMT: For example, in a computer set to EDT time (\$TimeZone === -4.), that date object in canonical form is:

DateList@DateObject[{1970, 1, 1, 0, 0, 0}, TimeZone -> 0]
(* {1969, 12, 31, 20, 0, 0.} *)
AbsoluteTime@%
(* 2 208 974 400 *)


To compute UNIX time, we need to find the difference between the current time and the origin. We can either take the difference of the respective AbsoluteTimes (with the computation done in our time zone):

AbsoluteTime[] -
AbsoluteTime[
DateObject[{1970, 1, 1, 0, 0, 0}, TimeZone -> 0]] // Round
(* 1427139257 *)


We could also forgo AbsoluteTime and ask Mathematica more directly what the difference is:

DateDifference[DateObject[{1970, 1, 1, 0, 0, 0}, TimeZone -> 0],
DateObject[], "Second"] // Round
(* Quantity[1427139257, "Seconds"] *)


Note that this emits a Quantity object. With Mathematica's built-in unit support, I find this more useful, although you can always strip out the value with QuantityMagnitude.

The times given by both of these methods agree with Wolfram|Alpha's answer.

The answer is that Mathematica's AbsoluteTime[] returns the number of seconds since 1900-01-01_00:00:00 in your system's time zone. So you probably don't want to use AbsoluteTime[] the way you use epoch time in other languages, where you can count on it to be consistent and universal across systems. So the following seems to consistently give actual current Unix time:

Round[AbsoluteTime[TimeZone -> 0] - AbsoluteTime[{1970, 1, 1, 0, 0, 0}]]


But I'm still confused; why isn't the second call to AbsoluteTime like so:

AbsoluteTime[{1970, 1, 1, 0, 0, 0}, TimeZone->0]


## Update: Here's what to actually do

In light of @Karsten's answer and taking the insight from @2012rcampion's answer, here's what I now recommend:

(* Mathematica 10.1 introduced UnixTime; this is a backport *)
If[Names["UnixTime"] == {},
UPOCH = AbsoluteTime[DateObject[{1970,1,1, 0,0,0}, TimeZone->0]];
UnixTime[x___] := Round[AbsoluteTime[x] - UPOCH];
FromUnixTime[t_] := DateObject[AbsoluteTime[t+UPOCH]];
];


That will work for most things you'll want it for in old versions, I believe, and no need to even change your code when you upgrade. That chunk just becomes superfluous.

• Because {1970, 1, 1, 0, 0, 0} still represents a time in your time zone. Try this instead: AbsoluteTime[TimeZone -> 0] - AbsoluteTime[DateObject[{1970, 1, 1, 0, 0, 0}, TimeZone -> 0], TimeZone -> 0], or simply AbsoluteTime[] - AbsoluteTime[DateObject[{1970, 1, 1, 0, 0, 0}, TimeZone -> 0]] Mar 23 '15 at 19:23
• Ah, thank you! I'll update this answer later to incorporate this unless you want to turn this into a separate answer. Mar 23 '15 at 19:39
• oops, already done.... I need to refresh the comments more frequently it seems Mar 23 '15 at 20:25
• Keep in mind that AbsoluteTime[] ignores leap seconds. I think this fact is missing in the documentation. Mar 24 '15 at 20:09
• @RolfMertig, is that different from what epoch times in other languages do? Mar 24 '15 at 23:07

Since version 10.1 of Mathematica there are the functions UnixTime and FromUnixTime performing the conversion between Unix times and DateObjects.

Current Unix time:

UnixTime[]


1427795462

UPOCH:

AbsoluteTime@FromUnixTime[0, TimeZone -> 0]


2208996000