C# 将Matlab Datenum转换为Datetime

C# 将Matlab Datenum转换为Datetime,c#,datetime,matlab,C#,Datetime,Matlab,-我希望转换Matlab串行时间(datenum,如t\u Matlab=now) 到c#Datetime(如var t#cs=Datetime.Now.Ticks) 你知道怎么做吗 [编辑]我找到了一种方法,但仍然不确定这是否是最好的方法。 [Edit2]修正了错误的日期时间,谢谢Jonas function cstime = datenum2datetime( matlabSerialTime ) %Convert matlab serial time (datenum) to .net d

-我希望转换Matlab串行时间(datenum,如
t\u Matlab=now

到c#Datetime(如
var t#cs=Datetime.Now.Ticks

你知道怎么做吗

[编辑]我找到了一种方法,但仍然不确定这是否是最好的方法。
[Edit2]修正了错误的日期时间,谢谢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;

编辑:对jarr的回答感到惊讶,我进一步调查。事实证明,sharhar\u m在问题中给出的示例时间点是错误的(很抱歉没有提前检查)

总之,问题中给出的函数关闭367-281=86天,应更正为

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

如果有人感兴趣,现在开始了解细节:您声称

%{05-Feb-2011 11:19:15}在System.DateTime中为634399319550000000

但是在MatlabR2010B中

sdt =System.DateTime(634399319550000000); 
[sdt.Day sdt.Month]
返回
[2 5]
,因此您的日期时间值实际上是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文档

“序列日期编号表示 整天数和小数天数 从0000年1月1日到特定日期。 0000年仅仅是一个参考 这一点并不意味着 解读为真实的一年。”

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

“100纳秒间隔的数量 从12点到现在已经过去了 0001年1月1日午夜,哪天 表示DateTime.MinValue。它是 不包括所需的刻度数 可归因于闰秒。”


总之,两个系统之间的“时间原点”相差一个闰年和一天,即367天。如果你真的想处理那么久远的真实日期,你必须考虑到改革和奥古斯都对8年前闰年错误应用的修正。。。但我怀疑这是否有意义;-)

使用此选项将matlab序列日期号转换为System.DateTime刻度:

function datetimeticks = mt2dt(matlabserialtime) 
    datetimeticks = (matlabserialtime - 367)*86400/1e-7;  
end
以及一个示例(在Matlab中):

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

function matlabserialtime = dt2mt(datetimeticks)
    matlabserialtime = double(datetimeticks) * 1e-7/86400 + 367;
end
以及一个示例(在Matlab中):

请注意,一旦从DateTime ticks转换为Matlab,就会丢失DateTimeKind信息。

您可能希望保留该选项,然后将其与SpecifyKind或DateTime ctor一起使用。

如果您仍然在任何地方使用上述函数,请务必阅读我的更新答案(以及jbarr的答案,其中指出了问题所在)。您当前的代码已关闭86天!
function matlabserialtime = dt2mt(datetimeticks)
    matlabserialtime = double(datetimeticks) * 1e-7/86400 + 367;
end
sdt = System.DateTime.Parse('8/6/1901 07:50:13');
mdt = datenum(dt2mt(sdt.Ticks));

>> datestr(mdt)

ans =

06-Aug-1901 07:50:13