对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。

$dateAdd(表达式操作符)

$dateAdd

版本 5.0 中的新增功能。

将 Date() 对象递增指定数量的时间单位。

$dateAdd 表达式的语法如下:

{ $dateAdd: { startDate: <Expression>, unit: <Expression>, amount: <Expression>, timezone: <tzExpression> }}

返回 Date()。startDate 可以是解析为 Date、Timestamp 或 ObjectId 类型的任何表达式。无论使用哪种数据类型作为输入,返回的值都将是 Date() 对象。

字段
必需/可选
说明

startDate

必需

加法运算的开始日期(以 UTC 为单位)。startDate 可以是任何可解析为日期、时间戳或对象标识符的表达式。

unit

必需

用于测量添加到 startDate 中的时间 amount 的 unit。unit 是一个表达式,可解析为以下字符串之一:

  • year

  • quarter

  • week

  • month

  • day

  • hour

  • minute

  • second

  • millisecond

amount

必需

添加到 startDate 中的 units 个数。amount 是解析为整数或长整数的表达式。amount 也可以解析为十进制整数或 double,前提是该值可以在不降低精度的情况下转换为长整数。

timezone

Optional

执行操作的时区。<tzExpression> 必须是一个有效的 表达式 ,解析为格式为 Olson 时区标识符 或 UTC 偏移 的 string:

  • Olson 时区标识符:例如 "America/New_York"、"Europe/London"、"GMT"

  • UTC 偏移:示例 "+04:45"、"-0530"、"+03"

如果您省略 timezone,则结果将在 UTC 中显示。

有关表达式和类型的更多信息,请参阅表达式和BSON types。

MongoDB 遵循流行的数据库使用情况并使用 UTC 时间。dateAdd 表达式始终采用 UTC 格式的startDate 并返回 UTC 格式的结果。如果指定了 timezone,则将使用指定的 timezone 完成计算。当计算涉及夏令时 (DST) 时,时区尤其重要。

如果 unit 为 month,则操作将调整以考虑该月的最后一天。例如,在 10 月的最后一天添加一个 month,结果演示了“月末最后一天”调整。

{ $dateAdd: { startDate: ISODate("2020-10-31T12:10:05Z"), unit: "month", amount: 1 }}

请注意,返回的日期 ISODate("2020-11-30T12:10:05Z") 是 30 日,而不是 31 日,因为 11 月的天数比 10 月少。

在 <timezone> 字段中使用 Olson 时区标识符时,如果适用于指定的时区,MongoDB 会应用 DST 偏移量。

例如,考虑包含以下文档的 sales 集合:

db.sales.insertOne( { "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:15:39.736Z") })

以下聚合说明了 MongoDB 如何处理 Olson 时区标识符的 DST 偏移量。该示例使用 $hour 和 $minute 操作符返回 date 字段的相应部分:

db.sales.aggregate([{ $project: { "nycHour": { $hour: { date: "$date", timezone: "-05:00" } }, "nycMinute": { $minute: { date: "$date", timezone: "-05:00" } }, "gmtHour": { $hour: { date: "$date", timezone: "GMT" } }, "gmtMinute": { $minute: { date: "$date", timezone: "GMT" } }, "nycOlsonHour": { $hour: { date: "$date", timezone: "America/New_York" } }, "nycOlsonMinute": { $minute: { date: "$date", timezone: "America/New_York" } } }}])

操作返回以下结果:

{ "_id": 1, "nycHour" : 5, "nycMinute" : 24, "gmtHour" : 10, "gmtMinute" : 24, "nycOlsonHour" : 6, "nycOlsonMinute" : 24}

考虑包含以下文档的客户订单集合:

db.shipping.insertMany( [ { custId: 456, purchaseDate: ISODate("2020-12-31") }, { custId: 457, purchaseDate: ISODate("2021-02-28") }, { custId: 458, purchaseDate: ISODate("2021-02-26") } ])

正常发货时间为 3 天。您可以在聚合管道中使用 $dateAdd 设置 expectedDeliveryDate 为未来 3 天。

db.shipping.aggregate( [ { $project: { expectedDeliveryDate: { $dateAdd: { startDate: "$purchaseDate", unit: "day", amount: 3 } } } }, { $merge: "shipping" } ] )

在 $project 阶段用 $dateAdd 给 purchaseDate 加了 3 天后,$merge 阶段用 expectedDeliveryDate 更新原始文档。

生成的文档如下所示:

{ "_id" : ObjectId("603dd4b2044b995ad331c0b2"), "custId" : 456, "purchaseDate" : ISODate("2020-12-31T00:00:00Z"), "expectedDeliveryDate" : ISODate("2021-01-03T00:00:00Z")}{ "_id" : ObjectId("603dd4b2044b995ad331c0b3"), "custId" : 457, "purchaseDate" : ISODate("2021-02-28T00:00:00Z"), "expectedDeliveryDate" : ISODate("2021-03-03T00:00:00Z")}{ "_id" : ObjectId("603dd4b2044b995ad331c0b4"), "custId" : 458, "purchaseDate" : ISODate("2021-02-26T00:00:00Z"), "expectedDeliveryDate" : ISODate("2021-03-01T00:00:00Z")}

使用以下代码更新上一个示例中的 shipping 集合,以将交付日期添加到文档中:

db.shipping.updateOne( { custId: 456 }, { $set: { deliveryDate: ISODate( "2021-01-10" ) } }) db.shipping.updateOne( { custId: 457 }, { $set: { deliveryDate: ISODate( "2021-03-01" ) } }) db.shipping.updateOne( { custId: 458 }, { $set: { deliveryDate: ISODate( "2021-03-02" ) } })

您想要找到延迟发货的订单。在 $match 阶段使用 $dateAdd 来创建筛选器,以匹配在由起始点 ($purchaseDate) 和由$dateAdd 给定的时间段共同确定的日期范围内的文档。

db.shipping.aggregate( [ { $match: { $expr: { $gt: [ "$deliveryDate", { $dateAdd: { startDate: "$purchaseDate", unit: "day", amount: 5 } } ] } } }, { $project: { _id: 0, custId: 1, purchased: { $dateToString: { format: "%Y-%m-%d", date: "$purchaseDate" } }, delivery: { $dateToString: { format: "%Y-%m-%d", date: "$deliveryDate" } } } } ])

$match 阶段在表达式 ($expr) 中使用 $gt 和 $dateAdd 将实际 deliveryDate 与预期日期相比较。交付日期超过 purchaseDate 后 5 天的文档将被传送到 $project 阶段。

$project阶段使用$dateToString表达式将日期转换为更具可读性的格式。 如果不进行转换,MongoDB 会以ISODate格式返回日期,并采用 UTC 时区。

在此示例中,仅返回一条记录:

{ "custId" : 456, "purchased" : "2020-12-31", "delivery" : "2021-01-10" }

所有日期均以 UTC 时间存储在内部。指定 timezone 时,$dateAdd 使用当地时间进行计算。结果以 UTC 时间显示。

您的客户分布在多个时区,您想了解如果您在 day 或 hour 之前计费,夏令时可能会对计费周期产生什么影响。

创建此连接时间的集合:

db.billing.insertMany( [ { location: "America/New_York", login: ISODate("2021-03-13T10:00:00-0500"), logout: ISODate("2021-03-14T18:00:00-0500") }, { location: "America/Mexico_City", login: ISODate("2021-03-13T10:00:00-00:00"), logout: ISODate("2021-03-14T08:00:00-0500") } ])

首先向每个文档中的 login 日期添加 1 天,然后添加 24 小时。

db.billing.aggregate( [ { $project: { _id: 0, location: 1, start: { $dateToString: { format: "%Y-%m-%d %H:%M", date: "$login" } }, days: { $dateToString: { format: "%Y-%m-%d %H:%M", date: { $dateAdd: { startDate: "$login", unit: "day", amount: 1, timezone: "$location" } } } }, hours: { $dateToString: { format: "%Y-%m-%d %H:%M", date: { $dateAdd: { startDate: "$login", unit: "hour", amount: 24, timezone: "$location" } } } }, startTZInfo: { $dateToString: { format: "%Y-%m-%d %H:%M", date: "$login", timezone: "$location" } }, daysTZInfo: { $dateToString: { format: "%Y-%m-%d %H:%M", date: { $dateAdd: { startDate: "$login", unit: "day", amount: 1, timezone: "$location" } }, timezone: "$location" } }, hoursTZInfo: { $dateToString: { format: "%Y-%m-%d %H:%M", date: { $dateAdd: { startDate: "$login", unit: "hour", amount: 24, timezone: "$location" } }, timezone: "$location" } }, } } ]).pretty()

$dateToString 表达式将输出重新格式化,以提高可读性。现将结果汇总如下:

字段
New York
墨西哥城

开始

2021-03-13 15:00

2021-03-13 10:00

开始,TZ Info

2021-03-13 10:00

2021-03-13 04:00

1 天

2021-03-14 14:00

2021-03-14 10:00

1 天,TZ Info

2021-03-14 10:00

2021-03-14 04:00

24 小时

2021-03-14 15:00

2021-03-14 10:00

24 小时,TZ Info

2021-03-14 11:00

2021-03-14 04:00

该图表突出显示以下几点:

  • 未格式化的日期以 UTC 格式返回。纽约的 $login 为 UTC -5,但start、days 和 hours 行显示 UTC 时间。

  • 3 月 14 日是纽约而不是墨西哥的夏令时开始时间。当一个位置切换到夏令时并从一个 day 跨越到下一个时,计算出的时间会进行调整。

  • DST 修改 day 的长度,而不是 hour 的长度。hours 的 DST 没有变化。仅当测量值 unit 不低于 day 且计算跨越指定的 timezone 中的时钟变化时,才会对 DST 进行调整。

给本页内容打分

在此页面上