首页/数据/NoSQL 速查/ISODate 与时间范围查询
MongoDB99 条

ISODate 与时间范围查询

日期以 UTC 毫秒存储:mongosh 用 ISODate("...Z") 构造,查询区间按 UTC 换算,避免本地时区偏移踩坑。

NoSQL 速查数据更新于 2026-10-13

日期怎么存怎么比

MongoDB 的 Date 是 BSON 日期类型,内部存 UTC 毫秒时间戳(自 1970-01-01 起的整数),与时区无关。mongosh 里的 ISODate("...") 就是 JS Date 的别名,查询时按 UTC 换算区间,展示时才按本地时区渲染。

基本信息

适用版本MongoDB 4.x-8.x / mongosh
存储格式BSON Date,UTC 毫秒
构造方式ISODate("2026-10-01T00:00:00Z") / new Date(毫秒数)
区间查询$gte + $lt 组成半开区间
精度毫秒,无纳秒/微秒

典型使用场景

  • 按天/按小时统计:先用 UTC 区间框住数据,再用 $dateToString 指定时区格式化
  • 增量抽取与对账:用 updatedAt 区间拉数据,半开区间避免边界重复
  • TTL 自动清理:对 Date 字段建 expireAfterSeconds 索引,到期自动删文档
  • 分页排序:按 ts 倒序翻页,用 (ts, _id) 组合保证顺序稳定
  • 跨时区系统统一口径:入库统一 UTC,展示层再转北京时间

查一天数据

查一天数据
db.orders.find({ ts: { $gte: ISODate("2026-10-01T00:00:00Z"), $lt: ISODate("2026-10-02T00:00:00Z") } })  # UTC 自然日
db.orders.find({ ts: { $gte: new Date("2026-10-01T08:00:00+08:00") } })      # 带偏移量,等价 UTC 00:00
db.orders.find({ ts: { $gte: new Date(Date.now() - 24*3600*1000) } })        # 最近 24 小时窗口
db.orders.aggregate([ { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$ts", timezone: "+08:00" } }, n: { $sum: 1 } } } ])  # 按北京时间归日

常见写法与含义

写法含义注意点
ISODate("2026-10-01T00:00:00Z")带 Z 的 UTC 时间点最明确,跨时区场景优先用这种
ISODate("2026-10-01")按 UTC 零点解释不会自动按本地时区,容易差 8 小时
new Date("2026-10-01T08:00:00+08:00")带偏移量的本地时间点等价 UTC 00:00,可读性好
Date.now()当前毫秒时间戳可直接做算术,如减去 7 天
"2026-10-01"字符串类型,不是日期与 Date 字段比较不会按预期命中
字符串和日期类型不互通:拿 "2026-10-01" 这样的字符串去比较 Date 字段,BSON 类型排序决定结果永远不符合业务预期,必须显式转换(new Date(...) 或 $dateFromString)。
需要范围查询、排序、TTL 过期或者聚合分组的字段,一定要存成 Date 而不是字符串;字符串存时间只能在写入端做格式化,查询侧基本失能。
查询北京时间 2026-10-01 这整天,对应 UTC 区间是 2026-09-30T16:00:00Z 到 2026-10-01T16:00:00Z;直接用 Z 零点当北京时间零点,会漏掉最前面 8 小时的数据。
mongosh 打印 ISODate 时按本机时区渲染,同一份文档在不同时区的机器上打印出的字符串不一样,但存储值与比较结果始终基于 UTC。核对对错请看 $gte/$lt 的边界,别拿打印出来的字面时间当依据。

易错点

  • 硬编码 UTC 零点当本地零点:北京时间 10-01 00:00 实际是 09-30T16:00Z,按天查询会少 8 小时数据
  • 用字符串存时间,$gte/$lt 变成字典序比较,跨格式数据结果不可控 → 统一存 Date
  • Date 只到毫秒,同一毫秒写入多条时无法靠时间排序稳定 → 加 _id 作次级键
  • TTL 索引字段类型不是 Date(或字段缺失)时过期扫描不会生效,文档长期堆积
  • 把 UTC 时间戳直接渲染给用户看,界面时间比本地差 8 小时引发对账纠纷 → 展示层显式转换时区

数据来源与参考

  • MongoDB Manual: Dates
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌