Skip to content

Instantly share code, notes, and snippets.

@tavert
Created October 15, 2013 13:48
Show Gist options
  • Save tavert/6991840 to your computer and use it in GitHub Desktop.
Save tavert/6991840 to your computer and use it in GitHub Desktop.
Helper functions for converting between Matlab datenum and Unix milliseconds
function out = datenum2unixmillis(in)
% convert Matlab datenum to unix milliseconds
% Matlab datenums are assumed to be in local time zone, unix ms are in UTC
[year, month, day, hour, minute, second] = datevec(in);
% java.util.GregorianCalendar constructor uses zero-based months and
% rounds seconds down to an integer, so handle seconds separately
time1 = java.util.GregorianCalendar(year(1), month(1)-1, ...
day(1), hour(1), minute(1), 0);
ms1 = time1.getTimeInMillis;
if numel(in) == 1
% shortcut for scalar input
out = ms1 + second(1)*1000;
return
end
% non-scalar input, check time zones and vectorize if possible
tz1 = time1.getTime.getTimezoneOffset; % in minutes
timeend = java.util.GregorianCalendar(year(end), month(end)-1, ...
day(end), hour(end), minute(end), 0);
msend = timeend.getTimeInMillis;
tzend = timeend.getTime.getTimezoneOffset;
if tz1 == tzend && (abs(msend - ms1) < 90*86400000) && ...
(min(in([1, end])) <= min(in)) && (max(in([1, end])) >= max(in))
% vectorize if all input times are in the same time zone
% max time interval of 3 months to be on the safe side with dst
out = ms1 + second(1)*1000 + (in - in(1))*86400000;
else
% for loop if time zone changes
ms = zeros(size(in)); % preallocate
ms(1) = ms1;
ms(end) = msend;
for i=2:numel(in)-1
ms(i) = java.util.GregorianCalendar(year(i), month(i)-1, ...
day(i), hour(i), minute(i), 0).getTimeInMillis;
end
out = ms + second*1000;
end
function out = unixmillis2datenum(in)
% convert unix milliseconds to Matlab datenum
% unix ms are in UTC, Matlab datenums are output in local time zone
datenum_utc = datenum(1970, 1, 1, 0, 0, 0) + double(in)/86400000;
% adjust for time zone
time1 = java.util.GregorianCalendar();
time1.setTimeInMillis(in(1));
tz1 = time1.getTime.getTimezoneOffset; % in minutes
if numel(in) == 1
% shortcut for scalar input
out = datenum_utc - tz1/1440;
return
end
% non-scalar input, check time zones and vectorize if possible
timeend = java.util.GregorianCalendar();
timeend.setTimeInMillis(in(end));
tzend = timeend.getTime.getTimezoneOffset;
if tz1 == tzend && (abs(in(end) - in(1)) < 90*86400000) && ...
(min(in([1, end])) <= min(in)) && (max(in([1, end])) >= max(in))
% vectorize if all input times are in the same time zone
% max time interval of 3 months to be on the safe side with dst
out = datenum_utc - tz1/1440;
else
% for loop if time zone changes
tz = zeros(size(in)); % preallocate
tz(1) = tz1;
tz(end) = tzend;
for i=2:numel(in)-1
timeend.setTimeInMillis(in(i));
tz(i) = timeend.getTime.getTimezoneOffset;
end
out = datenum_utc - tz/1440;
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment