DateTime,Epoch和DocumentDb

时间:2015-08-12 19:22:03

标签: c# epoch azure-cosmosdb

所以我读了这篇关于使用datetime in Azure DocumentDb的非常有趣的博客。问题是,目前,Azure DocumentDb不支持日期时间字段的范围搜索。原因是DocumentDb基于json并且没有日期时间类型,因此通常将它放在xml日期时间格式的字符串中。

(显然Mongo没有那个问题,它的bson格式添加了datetime类型(等等))

无论如何,文章描述了在一个纪元(unix)时间内将日期时间存储在json中,基本上将日期时间存储为自01-01-1970以来的秒数。时代的一个问题是它不会考虑闰秒,但我现在可以忍受这一点。

我的问题是,我还希望以这种格式存储出生日期。现在我可以将01-01-1900作为开始日期,并将自该日期以来的天数存储在int中。虽然我很确定这会很好用,但感觉epoch是一个完善的概念,但生日的感觉就像我正在构建我自己的约定,这是我一般都想避免的。

是否有将日期存储标准化为数字的既定标准?哪个日期应该是基准日期?

3 个答案:

答案 0 :(得分:17)

首先,更新:DocumentDB现在支持字符串和数字的范围索引。您必须正确设置索引才能使其正常工作。

现在,给你一个推荐。我成功地将ISO-8601时间戳存储为字符串。这是DocumentDB SDK用于处理DateTime的默认格式,因此它比转换为整数的工作少。

ISO-8601日期/时间字符串具有多个符合您需求的属性。

  1. 字母数字排序顺序是按时间顺序排列的,因此使用>,<,> =,< =和BETWEEN的查询子句可以完美地运行,假设您有适当精度的范围索引(-1表示全精度);
  2. 它们是人类可读的,因此如果您正在浏览表格,数据是有意义的;
  3. 此格式允许指定较低粒度的日期/时间。例如,您应该将“2015-03”表示行军月份,或“2015-03-24”表示2015年3月24日。然后,您可以使用此过滤器发出查询“startedOn> = 2015-03 -24 AND startedOn< 2015-03-25“查找从2015年3月24日开始的所有内容。即使将startedOn存储为完整的ISO-8601字符串,例如”2015-03-24T12:34:56.789Z“,这也有效由于字符串比较的性质。
  4. 我已经写过这种方法here

答案 1 :(得分:3)

The answer by Teo是正确的,除了我怀疑是否已经建立了#34;数十亿的Microsoft Excel,LibreOffice和Lotus 1-2-3电子表格都有自己的时代可能远远超过Unix时间使用量。或者十亿的Apple Cocoa设备和计算机都有自己的时代。

请注意,各种计算机环境都使用了couple dozen different epochs。 Unix时间远不是孤军奋战甚至是统治者。

还要注意,Unix time没有确切的事情。变化包括使用整秒,毫秒,微秒或纳秒。

如果可能,请使用日期时间精明数据类型。一定要学习文档和实验,以清楚地了解它的行为。

如果无法使用数据类型,则回退到使用各种ISO 8601格式的字符串。其中一些标准格式按字母顺序排列,特别是对于仅限日期的值:YYYY-MM-DD。

我知道的每个日期时间跟踪系统都会忽略闰秒。他们的目的是使我们的每小时时钟与日历一致,所以出于商业目的,Leap Second在某种意义上是被忽略的。

日期时间的工作令人惊讶地变得棘手而且很滑。搜索StackOverflow以发现许多问题。尽量避免滚动自己的解决方案。特别是对于C#,请查看Noda Time library

答案 2 :(得分:1)

根据我的经验,我没有遇到比UNIX时代更“既定”的标准。话虽如此,之前已经讨论过时间存储的一些架构/技术方面: Timestamps and time zone conversions in Java and MySQL

我会问为什么冒险使用你自己的约定?这是一个风险,因为:如果有一段时间你会想要增加你的日数,也许能够根据他们出生那天的确切时间来订购人。问题可以扩展到:如果在某些时候你想要测量更通用或更细粒度的时刻会怎么样;您必须将整个功能(可能在应用程序的多个层中)转换为更通用的机制/约定。另一个(类似的)问题是:您是否总是为数据库中的人员测量一次千载难逢的事件,或者他们是否能够创建新的无限制事件?随着事件数量的增加,碰撞风险也会增加,日计数也不如以秒或毫秒为单位测量的时间戳。

UNIX时间基本上无处不在,您可以使用特殊方法在大多数编程语言中获取它。我将永远支持& amp;在我的项目中实现是这样的: http://www.currentmillis.com/tutorials/system-currentTimeMillis.html

Architecture that stores time as a number

正如我在上面链接的问题的答案中所述,自UNIX时代以来存储时间为毫秒的优点是:

  • 架构清晰度:服务器端使用UTC,客户端显示 通过当地时区的时间
  • 数据库简单:你存储一个 数字(毫秒)而不是复杂的数据结构 DateTime是否
  • 编程效率:在大多数编程语言中 拥有自Epoch以来需要几毫秒的日期/时间对象 构造时(允许自动转换) 到客户端时区)

因为您提到了C#,所以会想到DateTime.MinValue。这基本上是0年(午夜,1月1日)。

此外,这将是一些代码,允许您从您选择的参考日期(无论它是什么)获得毫秒,但请注意1900仍然不同于.NET的'epoch'(DateTime.MinValue)

// Unix Epoch
(DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalMilliseconds
// NTP Epoch
(DateTime.UtcNow - new DateTime (1900, 1, 1)).TotalMilliseconds