比较datenum和18位数字时间戳

时间:2017-05-26 22:11:04

标签: .net matlab datetime timestamp data-conversion

我有两次夯实,我想在几秒钟内知道它们的区别。两个时间戳都接近

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)

现在,问题是时间戳不会同时开始计数。此外,我没有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`

有人暗示我犯了错误吗?

我已经尝试了很多。任何帮助表示赞赏。 非常感谢提前。

P.S。我不能快速回答。请耐心等待。

1 个答案:

答案 0 :(得分:2)

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 contain2^53,或略高于9e15)。并非每个高于该值的整数都可以完全表示,因此一旦开始存储大于双精度变量的整数,您将开始看到由于四舍五入到最近的精度而导致的精度损失可表示的浮点数。

由于您要将自己的号码转换为int64,这会让我相信您之前将其存储为其他内容(例如默认double),而其他内容只是赢了&#39 ;做。您希望确保从一开始就将其定义为int64,如下所示:

TS_signal1 = int64(634824637219781900);

现在,比较.NET和MATLAB datetimes(正如您所指出的)的一个关键问题是它们都在针对不同的参考时间点测量不同的数量:滴答(以100纳秒为单位),因为{{1分别来自1-JAN-0001以来的分数天数。我们需要考虑这个差异来比较这两个数字。一种方法是先将添加时间添加到.NET日期时间,因为MATLAB日期时间的参考时间较早,而且相对于该时间的测量结果要大得多。

那么,我们应该加多少时间?乍一看,只需减去参考时间(0-JAN-0000减去1-JAN-0001)就会建议我们将1。1年和1天添加到.NET日期时间,以便它表示来自{{1}的刻度数}。这很接近,但不是很正确。由于0-JAN-0000在技术上被视为闰年,因此它需要额外的一天,因此您实际上必须将1年和 2天的额外费用添加到.NET datetime。我们可以用数学做到这一点,或者我们可以使用System.DateTime类及其一些方法来快速简便地使用它:

0-JAN-0000

现在我们有0000的滴答数。我们可以将此转换为秒以继续我们的计算。但是,转换为秒需要将其更改为浮点表示(即ticks1 = System.DateTime(TS_signal1).AddYears(1).AddDays(2).Ticks; ),这会导致精度损失,因为我们的数字仍然很大。最好以刻度为单位继续计算。

MATLAB serial date number

您的MATLAB日期时间,表示为序列日期编号(0-JAN-0000),是一个浮点值,用于衡量自double以来经过的(小数)天数。为了与我们的.NET日期时间进行比较,我们需要将其转换为刻度,因此我们应该将其缩放735117.446046926(即小时/天时间秒/小时刻度/秒,刻度为100纳秒)。但这里存在一个问题。如果我们一次应用所有这些缩放,我们再次压倒我们的0-JAN-0000变量,其整数太大而无法处理,从而导致精度损失。但我们并不想将24*3600*1e7转换为double,直到我们将其扩展到足以获得整数值,否则我们可能会将小数信息四舍五入。

解决方案非常简单:应用尽可能多的缩放以获得仍然小于double的大整数,转换为int64,然后应用剩余的缩放:

2^53

全部放在一起

我们现在可以计算两个时间点之间的刻度(和秒)差异:

int64

要确认,我们将其转换为TS_signal2 = 735117.446046926; ticks2 = int64(TS_signal2*1e9)*24*36; duration并与日期字符串进行比较:

dTicks = ticks1 - ticks2;          % Difference in ticks (100 nanoseconds)
dSeconds = double(dTicks)*(1e-7);  % Difference in seconds

dSeconds =
     2.518352378360000e+04

我们可以看到两次确实相差6小时59分43秒。我们可以将日期时间数转换为日期字符串,然后提取小时,分钟和秒并完成一些数学运算以获得答案,但我们在此过程中会失去相当多的精确度。像我们上面那样以刻度为单位计算事物尽可能保持精确度......

...并且保持所有精确度并不好吗?