将Matlab Datenum转换为Datetime

时间:2011-05-02 08:52:12

标签: c# datetime matlab

- 我希望转换Matlab序列时间(datenum,如t_matlab=now
到c#Datetime(如var t_cs = DateTime.Now.Ticks)。

知道怎么做吗?

[编辑]我找到了一种方法,但仍不确定这是否是最佳方式 [Edit2]修正了错误的DateTimes,感谢Jonas!

function cstime = datenum2datetime( matlabSerialTime )
%Convert matlab serial time (datenum) to .net datenum.
%
%   Example:
%   ntTime = datenum2datetime(now)
%   cstime = datenum2datetime([734539.4717013890 734539.5051388888]);
%
%   See also datenum.

%   using System.DateTime.Parse(string).Ticks to convert to DateTime format.
%   t1 = now; t2 = now+1; matlab_times = [t1 t2];
%   cs_times = [System.DateTime.Parse(datestr(t1)).Ticks ...
%            System.DateTime.Parse(datestr(t2)).Ticks]
%   aver = diff(cs_times)/diff(matlab_times);
%   offver = cs_times(1) - matlab_times(1)*aver;

a = 10^7*60*60*24;
offset = -367*10^7*60*60*24;
cstime = a*matlabSerialTime + offset;

2 个答案:

答案 0 :(得分:5)

编辑:对jarr的回答感到惊讶,我进一步调查了一下。事实证明, sharhar_m在问题中给出的示例时间点是错误的(对不起以前检查)。

总结,问题中给出的功能已经过了367-281 = 86天,应该更正为

function cstime = datenum2datetime( matlabSerialTime )
cstime = 10^7*60*60*24*(matlabSerialTime - 367);

现在了解详情,如果有人有兴趣:您声明

  System.DateTime中的

%{05-Feb-2011 11:19:15}是634399319550000000

但在MATLAB R2010b

sdt =System.DateTime(634399319550000000); 
[sdt.Day sdt.Month]

返回[2 5],所以你的DateTime值实际上是5月2日,而不是2月5日!!要计算正确的值集

cs_times = [System.DateTime.Parse('05-Feb-2011 11:19:15').Ticks ...
            System.DateTime.Parse('05-Feb-2011 12:07:24').Ticks]

给出了[634325015550000000 634325044440000000]

时间单位缩放

您的因子a是10 ^ 7 * 60 * 60 * 24即MATLAB以“天”为单位存储日期/时间(以小时为单位的时间),C#将时间存储为“滴答”,即数字“10 ^ -7秒”。您可以通过输入a的精确值来避免一些舍入错误。

参考时间点的差异

以天(b)表示的偏移b/a告诉您他们的“时间原因”相隔367天;使用b的旧值,这个时间为281天。 datestr个州的MATLAB文档

  

“序列日期编号表示   整数和分数天数   从1月1日0000到特定日期。   0000年仅仅是一个参考   并且不打算成为   被解释为真实的一年。“

(即使运行datestr(0,'dd-mm-yyyy HH-MM-SS')显示参考点实际上是0-Jan-0000)。 <{3}}是

  

“100纳秒间隔的数量   已经过了12:00:00   0001年1月1日午夜   表示DateTime.MinValue。确实如此   不包括那些滴答数   可归因于闰秒。“

总而言之,两个系统之间的“时间起源”相差一闰年和一天,因此为367天。如果你真的想要处理那些可以追溯的实际日期,那么你必须考虑C# ticks改革和奥古斯都校正对8年前Gregorian calendar中闰年的错误应用。 ..但我怀疑这里有兴趣; - )。

答案 1 :(得分:2)

使用此命令将matlab序列日期编号转换为System.DateTime ticks:

function datetimeticks = mt2dt(matlabserialtime) 
    datetimeticks = (matlabserialtime - 367)*86400/1e-7;  
end

一个例子(在Matlab中):

mdt = datenum('8/6/1901 07:50:13');  
sdt = System.DateTime(mt2dt(mdt));

>> sdt.ToString

ans = 

8/6/1901 07:50:13

从System.DateTime到Matlab序列日期编号的对应转换同样简单:

function matlabserialtime = dt2mt(datetimeticks)
    matlabserialtime = double(datetimeticks) * 1e-7/86400 + 367;
end

一个例子(在Matlab中):

sdt = System.DateTime.Parse('8/6/1901 07:50:13');
mdt = datenum(dt2mt(sdt.Ticks));

>> datestr(mdt)

ans =

06-Aug-1901 07:50:13

注意,一旦从DateTime刻度转换为Matlab,就会丢失DateTimeKind信息 您可能希望保留它,然后将其与SpecifyKind或DateTime ctor一起使用。