TL; DR,因为我在下面非常详细...
TS_signal1 = int64(634824637219781900); % .NET datetime number
TS_signal2 = 735117.446046926; % MATLAB datetime number
ticks1 = System.DateTime(TS_signal1).AddYears(1).AddDays(2).Ticks;
ticks2 = int64(TS_signal2*1e9)*24*36;
dTicks = ticks1 - ticks2; % Difference in ticks (100 nanoseconds)
dSeconds = double(dTicks)*(1e-7); % Difference in seconds
dSeconds =
2.518352378360000e+04 (just shy of 7 hours)
而现在,解释......
我将分别处理每个日期时间的转换,并以尽可能保持尽可能精确的方式,即使您不一定需要它,因为您处理的是两个小时数之间的差异...
.NET DateTime
我立即注意到的一件事是你的日期时间数( 6.348246372197819e+17 )远大于the maximum value a double-precision variable can reliably contain( 2^53 ,或略大于 9e15 ) . 并非每个高于该值的整数都可以精确表示,因此一旦开始存储大于双精度变量的整数,您将开始看到由于四舍五入到最近的可表示浮点数而导致的精度损失 .
由于您将数字转换为int64,这使我相信您将其存储为其他事先(如默认double),而其他事情则不会 . 您希望确保从一开始就将其定义为 int64 ,如下所示:
TS_signal1 = int64(634824637219781900);
现在,比较.NET和MATLAB datetimes(正如您所指出的)的一个关键问题是它们都针对不同的参考时间点测量不同的量:自 1-JAN-0001 以来的滴答(以100纳秒为单位)与自 0-JAN-0000 以来的分数天数 . 我们需要考虑这个差异来比较这两个数字 . 一种方法是首先向.NET日期时间添加时间,因为MATLAB日期时间的参考时间较早,而且相对于该时间的测量值要大得多 .
那么,我们应该加多少时间?乍一看,只需减去参考时间( 1-JAN-0001 减去 0-JAN-0000 )就会建议我们在.NET日期时间中添加1年和1天,以便它表示来自 0-JAN-0000 的刻度数 . 这很接近,但并不完全正确 . 由于 0000 技术上算作闰年,它有一个额外的一天,所以你实际上必须在.NET日期时间增加1年和2天的额外刻度 . 我们可以用数学做到这一点,或者我们可以使用System.DateTime类及其一些方法来快速简便地使用它:
ticks1 = System.DateTime(TS_signal1).AddYears(1).AddDays(2).Ticks;
现在我们有关于 0-JAN-0000 的刻度数 . 我们可以将其转换为秒以继续我们的计算 . 但是,转换为秒需要将其更改为浮点表示(即 double ),这会导致精度损失,因为我们的数字仍然很大 . 最好以刻度为单位继续计算 .
MATLAB序列号
您的MATLAB日期时间(表示为序列日期编号( 735117.446046926 ))是一个浮点值,用于衡量自 0-JAN-0000 以来经过的(小数)天数 . 为了与我们的.NET日期时间进行比较,我们需要将其转换为刻度,因此我们应该将其缩放 24*3600*1e7 (即小时/天时间秒/小时刻度/秒,刻度为100纳秒) . 但这里有一个问题 . 如果我们立刻应用所有这些缩放,我们再次用一个太大而无法处理的整数来压倒我们的 double 变量,从而导致精度损失 . 但我们不希望将 double 转换为 int64 ,直到我们将其扩展到足以得到整数值,否则我们冒险四舍五入小数信息 .
解决方案非常简单:尽可能多地应用缩放以获得仍然小于 2^53 的大整数,转换为 int64 ,然后应用缩放的其余部分:
TS_signal2 = 735117.446046926;
ticks2 = int64(TS_signal2*1e9)*24*36;
把它们放在一起
我们现在可以计算两个时间点之间的滴答(和秒)差异:
dTicks = ticks1 - ticks2; % Difference in ticks (100 nanoseconds)
dSeconds = double(dTicks)*(1e-7); % Difference in seconds
dSeconds =
2.518352378360000e+04
要确认,让我们将其转换为 hh:mm:ss duration并与日期字符串进行比较:
durSec = seconds(dSeconds); % Convert to a duration...
durSec.Format = 'hh:mm:ss' % ... and format it
durSec =
duration
06:59:43
System.DateTime(TS_signal1).ToString % Convert .NET datetime to a string
ans =
9/5/2012 5:42:01 PM
datetime(TS_signal2, 'ConvertFrom', 'datenum') % Convert MATLAB datenum to a datetime
ans =
datetime
05-Sep-2012 10:42:18
我们可以看到两次确实相差6小时59分43秒 . 我们可以将日期时间数字转换为日期字符串,然后提取小时,分钟和秒并完成一些数学运算以获得答案,但我们在此过程中会失去相当多的精确度 . 像我们上面那样以刻度为单位计算事物尽可能保持精确度......
...并且保持所有精度都不是更好吗?