MongoDB中如何获取ISODate的本地时区小时值?
为什么MongoDB聚合
$hour提取的是UTC小时而非本地时区小时? 嘿,这个问题其实挺常见的,原因在于MongoDB日期聚合运算符的默认行为:
MongoDB中的$hour(以及$minute、$dayOfMonth等其他日期提取运算符)默认基于UTC时间进行计算。你的checkinData.time虽然显示为ISODate("2018-01-19T09:52:03.708+05:30"),但MongoDB内部会将其转换为UTC时间(也就是2018-01-19T04:22:03.708Z)来处理,所以提取出的小时就是4,而非你期望的本地时区9。
解决方案
根据你的MongoDB版本,有两种可行的解决方式:
1. MongoDB 3.6及以上版本(推荐)
从3.6版本开始,MongoDB的日期聚合运算符支持timezone参数,可以直接指定目标时区来提取小时:
db.checkins.aggregate([ {"$match": {"_id":"E08AF4BD-5539-497E-B8DA-51AD1A14F7A7"}}, {"$project":{ "checkinData.time": 1, hour: { $hour: { date: "$checkinData.time", timezone: "+05:30" // 也可以使用时区标识符如"Asia/Kolkata" } } }} ])
执行这段语句后,就能得到你想要的本地时区小时值9。
2. MongoDB 3.6以下版本
如果你的版本不支持timezone参数,可以借助$dateToString先将日期格式化为带时区的小时字符串,再转换为数字:
db.checkins.aggregate([ {"$match": {"_id":"E08AF4BD-5539-497E-B8DA-51AD1A14F7A7"}}, {"$project":{ "checkinData.time": 1, hourStr: { $dateToString: { format: "%H", date: "$checkinData.time", timezone: "+05:30" } } }}, {"$addFields": { hour: { $toInt: "$hourStr" } // 将字符串小时转为数字 }} ])
额外说明
MongoDB中的ISODate本质上是UTC时间戳,存储时会保留时区偏移信息,但聚合操作中的日期处理逻辑默认以UTC为基准,因此必须显式指定时区才能得到符合本地时区的时间部分。
内容的提问来源于stack exchange,提问作者Rahul Saini
相关产品推荐
相关产品推荐

