我有两次夯实,我想在几秒钟内知道它们的区别 . 两张时间戳都接近
5-9-2012 17:42:01
几小时(7小时) .
从信号1开始,我们有一个18位的时间戳(6.348246372197819e 17) . 时间戳从 1.JAN.0001 开始计算在100纳秒内 . 我想这是.NET时间的夯实(如果有人知道那个时间戳的具体名称会很棒) . (从邮票中查看时间表:)
TS1=System.DateTime(int64(TS_signal1));
TS1.ToString
从信号2我们有一个16位数的时间戳(735117.446046926) . (我猜Matlab datenum的序列日期编号) . 如果我没有弄错的话,Datenum是在 0.JAN.0000 的分数天 .
时间戳1可以通过将其乘以10 ^ -7(100Ns分辨率)轻松转换为秒 .
时间戳2通过乘以24 * 3600进行转换,对吗? (哪个分辨率有datenum [10ms?]?在乘法后,序列日期编号是浮点数:63514147338.4544)
Now, the problem 是时间戳不会同时开始计数 . 此外,我没有18位数时间戳(闰秒等)的信息 . 我试图通过从18位数字信号(顶部显示的日期)创建已知日期字符串的日期时间戳来获得差异 . 然后我在秒级别上减去了两个 . 差异是21427199.0218048
计算:
test=datenum('5-9-2012 17:42:01')% use date of 18 digit for datenum
test=test*24*3600 % convert to seconds
test-timestamp_18digits*10^(-7)
问题是现在如果我将其添加到信号2 datenum时间戳并减去信号1 18digit * 10 ^ -7时间戳我得到10281617.4543686秒的巨大差异,而它应该是7小时几秒 .
计算:`
...; % Get Signal 1 and 2 timestamps
TS_signal2_s=timeStartCam*24*3600+7*3600;
TS_signal2_s=TS_signal2_s+21427199.0218048; % adding the difference of the time stamps
offset_signals =TS_signal2_s-TS_signal1*(10^-7);%100ns`
有人暗示我犯了错误吗?
我已经尝试了很多 . 任何帮助表示赞赏 . 非常感谢提前 .
附:我不能快速回答 . 请耐心等待 .
1 回答
TL; DR,因为我在下面非常详细...
而现在,解释......
我将分别处理每个日期时间的转换,并以尽可能保持尽可能精确的方式,即使您不一定需要它,因为您处理的是两个小时数之间的差异...
.NET DateTime
我立即注意到的一件事是你的日期时间数(
6.348246372197819e+17
)远大于the maximum value a double-precision variable can reliably contain(2^53
,或略大于9e15
) . 并非每个高于该值的整数都可以精确表示,因此一旦开始存储大于双精度变量的整数,您将开始看到由于四舍五入到最近的可表示浮点数而导致的精度损失 .由于您将数字转换为int64,这使我相信您将其存储为其他事先(如默认double),而其他事情则不会 . 您希望确保从一开始就将其定义为
int64
,如下所示:现在,比较.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类及其一些方法来快速简便地使用它:现在我们有关于
0-JAN-0000
的刻度数 . 我们可以将其转换为秒以继续我们的计算 . 但是,转换为秒需要将其更改为浮点表示(即double
),这会导致精度损失,因为我们的数字仍然很大 . 最好以刻度为单位继续计算 .MATLAB序列号
您的MATLAB日期时间(表示为序列日期编号(
735117.446046926
))是一个浮点值,用于衡量自0-JAN-0000
以来经过的(小数)天数 . 为了与我们的.NET日期时间进行比较,我们需要将其转换为刻度,因此我们应该将其缩放24*3600*1e7
(即小时/天时间秒/小时刻度/秒,刻度为100纳秒) . 但这里有一个问题 . 如果我们立刻应用所有这些缩放,我们再次用一个太大而无法处理的整数来压倒我们的double
变量,从而导致精度损失 . 但我们不希望将double
转换为int64
,直到我们将其扩展到足以得到整数值,否则我们冒险四舍五入小数信息 .解决方案非常简单:尽可能多地应用缩放以获得仍然小于
2^53
的大整数,转换为int64
,然后应用缩放的其余部分:把它们放在一起
我们现在可以计算两个时间点之间的滴答(和秒)差异:
要确认,让我们将其转换为
hh:mm:ss
duration并与日期字符串进行比较:我们可以看到两次确实相差6小时59分43秒 . 我们可以将日期时间数字转换为日期字符串,然后提取小时,分钟和秒并完成一些数学运算以获得答案,但我们在此过程中会失去相当多的精确度 . 像我们上面那样以刻度为单位计算事物尽可能保持精确度......
...并且保持所有精度都不是更好吗?