在Matlab中将Epoch转换为日期

9

我在Matlab中有一个Epoch毫秒数的数组(数字数组)。我希望将这些转换成UTC日期时间格式,例如DD-MM-YYYY HH:MM。

是否有预定义的Matlab方法可以做到这一点,还是我需要编写自己的函数?


2
你可能正在寻找 datestr 函数。 - High Performance Mark
3个回答

22
假设你有一个向量 time_unix,那么:
>> time_unix = 1339116554872; % example time
>> time_reference = datenum('1970', 'yyyy'); 
>> time_matlab = time_reference + time_unix / 8.64e7;
>> time_matlab_string = datestr(time_matlab, 'yyyymmdd HH:MM:SS.FFF')

    time_matlab_string =

    20120608 00:49:14.872

注:

1)请查看Matlab的时间定义。

2)8.64e7是一天中的毫秒数。

3)Matlab不适用任何时区偏移,因此结果是相同的UTC时间。

4)反向转换的示例:

>> matlab_time = now;
>> unix_time = round(8.64e7 * (matlab_time - datenum('1970', 'yyyy')))

unix_time =

             1339118367664

总结一下,这里有两个函数:

function tm = unix2matlab(tu)
    tm = datenum('1970', 'yyyy') + tu / 864e5;
end
function tu = matlab2unix(tm)
    tu = round(864e5 * (tm - datenum('1970', 'yyyy')));
end

这里的Matlab时间是数值型的。您可以使用datestr()将其转换为字符串。

关于纳秒的更新

time_unix_nanos = 1339116554872666666;
millis = round(time_unix_nanos / 1e6);
nanos = time_unix_nanos - 1e6 * millis;
time_matlab = unix2matlab(millis);
s = [datestr(time_matlab, 'yyyymmdd HH:MM:SS.FFF'), num2str(nanos)];

        s =
        20120608 00:49:14.872666666

太棒了。需要注意的是,现在有些Unix时间戳是微秒(甚至纳秒)级别的,因此864e5可能需要变成864e8或者甚至是864e11 - charleslparker
我遇到了以下错误:“Error using datevecmx The datevecmx function only accepts double arrays. ” - Maxtron
..."微型或纳米级",好的,只需相应地进行划分。 - Serg
应用double()。在Matlab中,默认情况下所有数字都是double类型,因此“time_unix = 1339116554872;”也是double类型。 - Serg

1
我尝试了上述代码,但结果是错误的。我意识到主要错误与Unix时间(纪元时间)的定义有关。Unix时间(纪元时间)定义为从1970年1月1日00时00分起的秒数,而不是**毫秒数**(http://en.wikipedia.org/wiki/Unix_time)。根据这个定义,Unix时间应该被8.64e5而不是8.64e7除。

此外,datenum('1970', 'yyyy')似乎并没有产生所需的参考时间1970年1月1日00时00分。

这是我改进后的代码:

tMatlab = datenum (1970,1,1,0,0) + tUnix / 86400;

8.64e7 是一天的毫秒数。如果您的时间戳是以秒为单位的,则应使用 8.64e4(即 86400),而不是 8.64e5。 - Serg

0

Serg的回答是我在MATLAB中通常使用的方法。今天我发现自己想要在MATLAB中进行日期转换,就像标题所说的那样 - 在没有指定问题正文中的日期字符串转换的情况下 - 并从shell输出日期数字。

这是我为四舍五入的日期数字所采用的方法:

TODAY_MATLAB="$[719529 + $[`date +%s` / 24/60/60]]"

这实际上只是bash中你所期望的等价物:719529是纪元(1970-01-01或在MATLAB中datenum(1970,1,1))的日期编号。我最近也在摸索ksh,似乎可以用以下方式完成:

TODAY_EPOCH=`date +%s`
TODAY_MATLAB=`expr $TODAY_EPOCH / 24 / 60 / 60 + 719529`

作为一个附带练习,我在中将小数部分重新添加到日期中 - 在ksh中我没有这样做,但这只是算术运算,方法类似:
N_DIGITS=7
FORMAT=$(printf "%%d.%%0%dd" $N_DIGITS)

NOW_EP_SEC=`date +%s` 
SEC_PER_DAY=$(( 24*60*60 )) 
NOW_EP_DAY=$(( $NOW_EP /$SEC_PER_DAY ))  
SEC_TODAY=$(( $NOW_EP_SEC - $NOW_EP_DAY*$SEC_PER_DAY )) 

TODAY_MATLAB="$(( NOW_EP_DAY+719529 ))"
FRACTION_MATLAB="$( printf '%07d' $(( ($SEC_TODAY*10**$N_DIGITS)/SEC_PER_DAY )) )"
MATLAB_DATENUM=$( printf $FORMAT $TODAY_MATLAB $FRACTION_MATLAB )

echo $MATLAB_DATENUM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接