Convert date to UNIX time

Hi,
What combination of date functions do I need to use to convert a date such as '24-Apr-2011' into UNIX time (and vice versa)?
I've been playing around with datenum, datestr and datetick but I can't figure it out
Thanks Dave

7 Comments

I've been struggling with this myself, and I've come up with the following system for doing this that accounts for leap seconds and such:
unix_time = seconds(datetime(2011,4,24) - datetime(1970,1,1))
The matlab datetime function accounts for leap seconds and such, but is not formatted in a convenient way to calculate seconds, so you have to take a time difference and convert it to seconds using the seconds function.
Though if you deal with leap seconds, then you start needing to be careful with the definitions of exactly what you are looking for. Classical "unix time", time_t, is defined as an unsigned 32 bit integer of seconds since Jan 1, 1970 00:00 UTC, and leap seconds are specifically excluded in the classical definition.
There are good reasons, especially in astronomy, to want to include leap seconds, but such situations seldom want "unix time" as an output (for example because it does not have enough resolution.)
Understood--and appreciated. In my own problem, I wasn't actually interested in accurately computing unix time, but in outputting an estimated date and time of completion of my code--and that requires combining dates with seconds of runtime. I ended up creating my own (short) functions for this purpose:
function S = gettime()
S = seconds(datetime('now') - datetime(1970,1,1));
end
function outstr = Seconds2DateTime(S)
outstr = datetime(1970,1,1) + seconds(S);
end
The choice of 1/1/1970 is arbitrary for these purposes, but I was nevertheless surprised that matlab didn't have built-in routines to perform these two tasks (inputting and outputting a date as seconds ellapsed from a specific start date and time).
I suppose concerning myself with leap seconds is a bit pedantic for those purposes, but I wanted it to be accurate.
You have to be careful about the base times.
function S = gettime()
S = seconds(datetime('now') - datetime(1970,1,1,'TimeZone','UTC'));
end
function outstr = Seconds2DateTime(S)
outstr = datetime(1970,1,1,'TimeZone','UTC') + seconds(S);
end
Thanks! I'll modify the code accordingly.
" I was nevertheless surprised that matlab didn't have built-in routines to perform these two tasks (inputting and outputting a date as seconds ellapsed from a specific start date and time)."
Of course it does, you can find them listed in the MATLAB documentation:
TN = datetime('now');
S0 = seconds(TN - datetime(1970,1,1)) % Your approach
S0 = 1.6901e+09
S1 = posixtime(TN) % inbuilt MATLAB function
S1 = 1.6901e+09
S2 = convertTo(TN,'posix') % inbuilt MATLAB function
S2 = 1.6901e+09
isequal(S0,S1,S2)
ans = logical
1
And if you really want to control the epoch and ticks per second (but lossy due to the numeric operations):
S3 = convertTo(TN,'epochtime','Epoch','1970-1-1', 'TicksPerSecond',1); % inbuilt MATLAB function
S3 = double(S3)
S3 = 1.6901e+09
And the reverse conversion is easy too:
T0 = datetime(1970,1,1) + seconds(S0) % your approach
T0 = datetime
22-Jul-2023 19:01:44
T1 = datetime(S0,'ConvertFrom','posix') % inbuilt MATLAB function
T1 = datetime
22-Jul-2023 19:01:44
T2 = datetime(S0,'ConvertFrom', 'epochtime','Epoch','1970-1-1','TicksPerSecond',1) % inbuilt MATLAB function
T2 = datetime
22-Jul-2023 19:01:44
The conversion to POSIX-double is lossy, so we do not expect exact equivalence (less than ns is not bad though):
milliseconds(T0-TN)
ans = -5.0783e-05
milliseconds(T1-TN)
ans = -5.0783e-05
milliseconds(T2-TN)
ans = -1.6141e-04
James Tursa
James Tursa on 22 Jul 2023
Edited: James Tursa on 22 Jul 2023
For completeness of this thread, I suppose I should add that this entire discussion with Unix Epoch of 1970-1-1 00:00 UTC assumes the redefinition of Unix Epoch using backwards extension of Modern UTC (TAI based), which didn't start until 1972. The original Unix Epoch based on Old UTC (UT based) is actually about 2 seconds different. But unless you are doing some type of historical work, you should use the redefinition with backwards extension of Modern UTC. The MATLAB datetime( ) function assumes this backwards extension. I am unaware of any MATLAB functions that use the Old UTC definition, so if you are doing historical work you will probably have to write your own conversion function.

Sign in to comment.

 Accepted Answer

In R2014b or later, use datetime:
>> d = datetime('24-Apr-2011')
d =
24-Apr-2011
>> posixtime(d)
ans =
1303603200
>> datetime(1303603200,'ConvertFrom','posixtime')
ans =
24-Apr-2011 00:00:00
Similar syntaxes for Excel serial date numbers, Julian date numbers, and not surprisingly MATLAB date numbers.
Hope this helps.

1 Comment

Probably worth noting that time zone will have an effect as well as the offset from UTC plays a role in the appropriate conversion.
>> d1 = datetime('24-Apr-2011');
>> p1 = posixtime(d)
p1 =
1.303603200000000e+09
>> d2 = datetime('24-Apr-2011','TimeZone','America/New_York');
>> p2 = posixtime(d2)
p2 =
1.303617600000000e+09

Sign in to comment.

More Answers (1)

int32(floor(86400 * (datenum('24-Apr-2011') - datenum('01-Jan-1970'))))
Note that both systems have the problem of not dealing with leap seconds.
Also, the int32() rather than uint32() is not an error: unix time was defined as a signed number.

5 Comments

Assuming the date is a UTC date, of course. Also, if one is converting dates with fractions of seconds, you might want to drop the int32(floor( )) part if it makes sense to keep the fractions for your particular application (i.e., "Unix time number").
UTC, yes.
You must use int32() if you are calculating Unix time. Unix time is defined as a 32 bit integer quantity, not as a floating point quantity.
James Tursa
James Tursa on 28 Sep 2015
Edited: Walter Roberson on 28 Sep 2015
There is apparently a distinction between the terms "Unix time" and "Unix time number", the latter being allowed to use any form for the representation, including a floating point quantity. Certainly if the application called for it I would not hesitate to use a floating point quantity.
Also, although traditionally the strict "Unix time" has been held in a signed 32-bit integer, from what I read this is "tradition" but is not a strict requirement ... signed 64-bit integers could be used as well. E.g.,
Ah, my answer is for time_t in particular. I have never encountered a Unix system that used a different representation.
Yes, for time_t I agree that it is typically implemented as a signed 32-bit integer.

Sign in to comment.

Categories

Asked:

on 24 Apr 2011

Edited:

on 22 Jul 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!