2016-01-21 45 views
3

保存我的交易的东西,如:MongoDB的骨料:日期转换到另一个时区

{code: "A", total: 250000, timestamp: ISODate("2016-01-20T23:57:05.771Z")}, 
{code: "B", total: 300000, timestamp: ISODate("2016-01-20T05:57:05.771Z")} 

交易的每个人都有下它UTC时区timestamp场。由于我住在雅加达(UTC + 7)时区,因此我需要在聚合之前将7小时添加到我的时间戳。这里是我的蒙戈语法:

db.transaction.aggregate(
[ 
{ 
    $project: 
    { 
     year: { $year: "$timestamp" }, 
     month: { $month: "$timestamp" }, 
     day: { $dayOfMonth: "$timestamp" } 
    } 
} 
]) 

它返回:

{ 
     "_id" : ObjectId("56a01ed143f2fd071793d63b"), 
     "year" : 2016, 
     "month" : 1, 
     "day" : 20 
    }, 
    { 
     "_id" : ObjectId("56a01ed143f2fd071793d63b"), 
     "year" : 2016, 
     "month" : 1, 
     "day" : 20 
    } 

这是因为第一个事务错误(代码A),是发生在1月21日,但因为它被转换为UTC(-7小时),它成为ISODate("2016-01-20T23:57:05.771Z")

注:我知道about the same problem over here,这里就是我一直到目前为止已经试过:

db.transaction.aggregate(
[ 
{$project: {"timestamp": {$add: [7 * 60 * 60 * 1000]}}}, 
{ 
    $project: 
    { 
     year: { $year: "$timestamp" }, 
     month: { $month: "$timestamp" }, 
     day: { $dayOfMonth: "$timestamp" } 
    } 
} 
]) 

但它返回can't convert from BSON type NumberDouble to Date错误。 有什么建议吗?

回答

3

您需要将“时间戳”添加到7 * 60 * 60 * 1000也可以在一个$project阶段执行此操作。

db.collection.aggregate([ 
    { "$project": { 
     "year": { "$year": { "$add": [ "$timestamp", 7 * 60 * 60 * 1000 ] } }, 
     "month": { "$month": { "$add": [ "$timestamp", 7 * 60 * 60 * 1000 ] } }, 
     "day": { "$dayOfMonth": { "$add": [ "$timestamp", 7 * 60 * 60 * 1000 ] } } 
    } } 
]) 

将返回:

{ 
     "_id" : ObjectId("56a07f8f8448ed9fd2359365"), 
     "year" : 2016, 
     "month" : 1, 
     "day" : 21 
} 
{ 
     "_id" : ObjectId("56a07f8f8448ed9fd2359366"), 
     "year" : 2016, 
     "month" : 1, 
     "day" : 20 
} 
+0

当您只有一个时区但不适用于动态时区时,这是一个很好的解决方案。 –

1

作为更新的MongoDB 3.6已经在聚合框架日期操作一个新的时区参数。大多数与日期相关的操作符都接受此可选参数,有关一个示例,请参见$hour

例如,如果我们有一个文档,其中的日期正好是在UTC新的一年里:

> db.test.find() 
{"_id": 1, "dt": ISODate("2018-01-01T00:00:00Z")} 

我们可以显示在纽约时区的日期:

> db.test.aggregate([ 
...  {$project:{ 
...   date:{$dayOfMonth:{date:'$dt',timezone:'America/New_York'}}, 
...   month:{$month:{date:'$dt',timezone:'America/New_York'}}, 
...   year:{$year:{date:'$dt',timezone:'America/New_York'}}, 
...   hour:{$hour:{date:'$dt',timezone:'America/New_York'}} 
...  }} 
... ]) 
{ "_id": 1, "date": 31, "month": 12, "year": 2017, "hour": 19 } 

我们也可以在悉尼时区显示日期:

> db.test.aggregate([ 
...  {$project:{ 
...   date:{$dayOfMonth:{date:'$dt',timezone:'Australia/Sydney'}}, 
...   month:{$month:{date:'$dt',timezone:'Australia/Sydney'}}, 
...   year:{$year:{date:'$dt',timezone:'Australia/Sydney'}}, 
...   hour:{$hour:{date:'$dt',timezone:'Australia/Sydney'}} 
...  }} 
... ]) 
{ "_id": 1, "date": 1, "month": 1, "year": 2018, "hour": 11 } 

这个时区的描述使用了标准的Olson Timezone Identifier string

相关问题