我发现一些数据存储在MongoDB中存在问题。我们有一个存储日期的字段,通常包含ISODate("1992-08-30T00:00:00.000Z")
或ISODate("1963-08-15T00:00:00.000Z")
等值。这很好,很直接;我可以很容易地看一下这些日期,看看1992年8月30日或1963年8月15日。
但是,我注意到有几个条目的日期看起来像这样:
Date(-61712668800000)
老实说,我不确定数据是如何以这种方式持续存在的,因为它应该以前一种方式存储。而且我必须使用我的代码来解决软件错误,该代码会间歇地导致它以这种方式存储。
然而,更大的问题是如何处理看起来像这样的数据条目。我甚至不确定应该是什么日期。我的第一个假设是,它只是毫秒,就像UNIX时间戳或其他什么,但那不对。即使我翻转负号并删除一些尾随零,这仍然是未来的日期方式(例如2165年7月23日),这是不正确的。它应该是过去的日期。
另一个大问题是我不确定如何在数据库中搜索这个。我无法使用$type
查询,因为the type仍为9(即它仍然认为它是"日期")。
之前有没有其他人遇到过这些奇怪的日期条目?我怎么才能找到它们?我怎样才能从中恢复实际日期?
答案 0 :(得分:5)
问题似乎是你的代码在纪元之前存储了日期,而且到目前为止,它们无法使用ISODate包装器来表示:
(强调补充)
日期
BSON Date是一个64位整数,表示数字 自Unix时代以来的毫秒(1970年1月1日)。这导致了 可表示的日期范围约为2.9亿年过去和 将来
官方BSON规范将BSON日期类型称为 UTC日期时间。
在版本2.0中更改:BSON日期类型已签名。 [2] 负值 代表1970年以前的日期。
虽然在Mongo文档中没有明确说明,但似乎他们遵循ISO 8601标准的严格解释,而不是基于我发现的{{3}“贸易伙伴协议”允许的变体之一}
年
YYYY±YYYYY ISO 8601至少规定a 四位数的年份[YYYY]以避免2000年的问题。因此 表示从0000到9999年,0000年等于1 BC和 所有其他人AD。但是,1583年之前的年份不是自动的 标准允许的。而是“在[0000]到[0000]范围内的值 [1582]只能在合作伙伴的共同协议下使用 信息交流。“[9]
表示0000之前或9999之后的年份,标准也是 允许扩大年度代表,但只能事先 发送者和接收者之间的协议。[10]扩大的一年 代表[±YYYYY]必须具有商定的额外年份数 超过四位数最小值的数字,并且必须以+为前缀 或 - 签署[11]而不是更常见的AD或BC(或更广泛的 使用BCE / CE)表示法;按照惯例,1 BC标记为+ 0000,BC为2 标记为-0001,依此类推。[12]
如果您仔细阅读本文的其余部分,您还会看到必须预先定义位数的原因是,可以明确地存储日期,而无需在组件之间使用分隔符,例如“ - ”。