Rya*_*yan 5 unix timezone jodatime unix-timestamp
如:
The Unix time number is zero at the Unix epoch, and increases by exactly 86400
per day since the epoch. So it cannot represent leap seconds. The OS will slow
down the clock to accomodate for this.
Run Code Online (Sandbox Code Playgroud)
那么,如果我在DB中存储Unix纪元(例如ts)(毫秒精度),如何处理以下情况?
例如
SELECT * FROM events WHERE ts >= T1 and ts < T1 + 100
Run Code Online (Sandbox Code Playgroud)
上面的SQL将返回发生在T1,T1 + 1,T1 + 2,..上升到T1 + 99的事件,但由于闰秒,结果可能是错误的,包括1s的跳跃时间,如何采取帐户到此?
首先我要说的是,我在现实生活中没有遇到过这样的问题,所以我只能猜测,但这将是一个有根据的猜测。根据http://en.wikipedia.org/wiki/Unix_time#Encoding_time_as_a_number,当插入闰秒时,问题是2次(例如1998-12-31T23:59:60.00和1999-01-01T00:00:00.00)具有相同的 Unix 时间 (915.148.800.000)。删除闰秒后应该不会有任何问题。
根据同一维基百科页面上的注释#2,闰秒是不可预测的,这给您提供了两种选择:一种通用解决方案(假设您有由这些时间戳索引的表)可以始终插入条目,并且一个条目发生在最后插入的条目(可能在闰秒内)您可以开始“涂抹”过程,该过程基本上是向条目添加一些毫秒以确保它超出闰秒的范围。当插入的条目再次具有比先前插入的条目更大的值时,该过程可以停止。我称其为“涂抹”,因为它在某种程度上受到 Google 的“Leap Smear”技术的启发(尽管不完全相同): http: //googleblog.blogspot.in/2011/09/time-technology-and-leaping-seconds.html 在我看来,这可能会给你的数据库带来一些压力,并且插入查询将是我见过的最复杂的查询之一(如果它甚至可以单独在 SQL 中实现的话)。
另一个解决方案可以是(我假设您使用的是 Java)手动检查时间戳是否落在闰秒内。如果是这样,只需阻止对数据库的任何访问并将条目插入队列中。当闰秒结束时,只需将队列以 FIFO 方式插入数据库即可保证您关心的顺序(类似于上面的解决方案,但完全用 Java 编写,因此在它接触 DB 层之前)。您可以通过消除队列并直接插入数据库来对此进行优化 - 只需像上面一样在一秒钟内“涂抹”条目即可。
当然,缺点是您在闰秒中牺牲了一点准确性(考虑到闰秒如此罕见,这并不是一个很大的牺牲),但优点是它很简单并且您的订单得到保证。
如果您或其他人找到更好的解决方案,请在这里分享,这个主题非常有趣:)
更新:我已经为第三个解决方案(完全在 SQL 查询中)编写了伪代码,该解决方案依赖于对闰秒的硬编码检查(比通用解决方案更快)。它可能可以优化很多,但只是为了证明我的观点:
if (newTime is in a leap second){
read smearCount from db;
if (smearCount <= 0) {
smearCount = 1000; // making sure we land outside the leap second
update smearCount in db;
}
newTime += smearCount;
insert newTime into db;
} else { // gradually reducing smearCount by 1 millisecond over the following 1000 insertions
read smearCount from db;
if (smearCount > 0){
smearCount -= 1;
update smearCount in db;
newTime += smearCount;
}
insert newTime into db;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
843 次 |
| 最近记录: |