如何更新集合并增加ISO日期的小时数

9 浏览
0 Comments

如何更新集合并增加ISO日期的小时数

我在我的文档集合中有一个ISO日期。

"start" : ISODate("2015-07-25T17:35:00Z"),
"end" : ISODate("2015-09-01T23:59:00Z"),

当前它们是在GMT +0时区,我需要它们在GMT +8时区。因此,我需要在现有字段上添加8小时。我应该如何通过mongodb查询来实现这个?

感谢您的建议。

更新的代码片段

var offset = 8,
bulk = db.collection.initializeUnorderedBulkOp(),
count = 0;
db.collection.find().forEach(doc) {
bulk.find({ "_id": doc._id }).updateOne({
   "$set": { “startDateTime": new Date(
       doc.startDateTime.valueOf() + ( 1000 * 60 * 60 * offset )
   ) }
});
count++;
if ( count % 1000 == 0 ) {
    bulk.execute();
    bulk = db.collection.initializeUnorderedBulkOp();
}
});
if ( count % 1000 !=0 )
    bulk.execute();

0
0 Comments

MongoDB默认将所有的日期时间存储为UTC时间。有两种方法可以实现这一点:

App端(推荐):从数据库中提取startend时,在您选择的编程语言中将其从UTC时间更改为本地日期时间。在Python中有一个很好的例子,可以参考这个回答

数据库端(不推荐):另一种选择是编写一个MongoDB查询,将8小时添加到startend中,就像您最初希望的那样。然而,这会将时间设置为UTC时间,并且比当前时间晚8小时,这对其他开发人员和解析应用程序端来说是不合逻辑的。

这需要根据文档中的另一个值进行更新,因此您将不得不遍历每个文档,如这里所述

0
0 Comments

如何更新集合并为ISO日期增加小时

有时候,在处理数据库中的时间时,我们需要考虑不同时区的情况。通常,我们会将所有时间都存储为UTC时间,并在需要时根据具体时区进行转换。这样可以确保数据的一致性和准确性。下面是一种处理方式。

假设有两个人使用数据,一个在纽约,一个在悉尼,分别处于UTC-5和UTC+10时区。现在考虑以下数据:

{ "date": ISODate("2015-08-01T04:40:03.389Z") }

根据这个数据,事件实际发生的时间是8月1日。对于悉尼的用户来说,事件是在8月1日发生的,而对于纽约的用户来说,事件仍在7月31日发生。

如果我们构建一个悉尼本地化的时间,UTC的考虑仍然是正确的:

new Date("2015/08/01")

ISODate("2015-07-31T14:00:00Z")

这样可以将本地时区转换为UTC时间。因此,使用本地化的日期可以在UTC中选择正确的值。因此,悉尼用户对8月1日的开始时间包括从7月31日下午2点开始的所有时间,并相应地调整到范围选择的结束日期。使用UTC数据,客户端的断言是正确的,根据他们的视角,所选数据在预期范围内。

如果您要对给定日期进行“聚合”,则需要在表达式中加入“时差”数学计算。对于UTC+10,您可以这样做:

var offset = 10;

db.collection.aggregate([

{ "$group": {

"_id": {

"$subtract": [

{ "$add": [

{"$subtract": [ "$date", new Date(0)]},

offset * 1000 * 60 * 60

]},

{ "$mod": [

{ "$add": [

{ "$subtract": [ "$date", new Date(0) ] },

offset * 1000 * 60 * 60

]},

1000 * 60 * 60 * 24

]}

]

},

"count": { "$sum": 1 }

}}

)

这样,当向查看数据的客户端返回“日期”时,将考虑所在位置的时区偏移量。因此,发生在“调整日期”上的任何事情,导致不同的日期(例如8月31日),将通过此调整聚合到正确的分组中。

因为您的数据很可能会从不同时区的人的角度来使用,这正是为什么应该将日期数据保留在UTC格式中的原因。客户端将会处理这些工作,或者您可以根据需要进行相应的调整。

简而言之:

- 客户端:使用本地时间构建,发送UTC时间。

- 服务器:提供时区偏移量,并在返回时从UTC调整为本地时间。

保持数据的正确格式,并使用此处描述的方法进行报告。

但如果你犯了个错误

然而,如果在构建数据时犯了错误,所有时间实际上是“本地”时间,但表示为UTC时间,例如:

ISODate("2015-08-01T11:10:43.569Z") //实际上应该是UTC+10时区的上午11点 🙁

正确的应该是:

ISODate("2015-08-01T01:10:43.569Z") //这是UTC+10时区的上午11点 🙂

那么你可以按如下方式进行更正:

var offset = 10,

bulk = db.collection.initializeUnorderedBulkOp(),

count = 0;

db.collection.find().forEach(function(doc) {

bulk.find({ "_id": doc._id }).updateOne({

"$set": { "date": new Date(

doc.date.valueOf() - ( 1000 * 60 * 60 * offset )

) }

});

count++;

if ( count % 1000 == 0 ) {

bulk.execute();

bulk = db.collection.initializeUnorderedBulkOp();

}

});

if ( count % 1000 !=0 )

bulk.execute();

通过读取每个文档并相应调整“date”值,将更新后的日期值发送回文档。

以上就是如何更新集合并为ISO日期增加小时的方法。

0