On this page本页内容
$dateDiff
New in version 5.0.在版本5.0中新增。
Returns the difference between two dates.返回两个日期之间的差值。
The $dateDiff
expression has this syntax:$dateDiff
表达式具有以下语法:
{ $dateDiff: { startDate: <Expression>, endDate: <Expression>, unit: <Expression>, timezone: <tzExpression>, startOfWeek: <String> } }
Subtracts 从startDate
from endDate
. endDate
中减去startDate
。Returns an integer in the specified 返回指定unit
.unit
的整数。
startDate | startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID.startDate 可以是解析为日期、时间戳或ObjectID的任何表达式。
| |||||||
endDate | endDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID.endDate 可以是解析为日期、时间戳或ObjectID的任何表达式。
| |||||||
unit |
| |||||||
timezone |
| |||||||
startOfWeek |
|
The $dateDiff
expression returns the integer difference between the startDate
and endDate
measured in the specified units
. $dateDiff
表达式返回以指定单位度量的startDate
和endDate
之间的整数差。Durations are measured by counting the number of times a unit boundary is passed. 持续时间是通过计算单位边界通过的次数来衡量的。For example, two dates that are 18 months apart would return 1 例如,两个相隔18个月的日期将返回1年的差异,而不是1.5年。year
difference instead of 1.5 years
.
The start of the 除非通过week
is Sunday
unless modified by the startOfWeek
parameter. startOfWeek
参数进行修改,否则一周的开始时间为周日。Any week that begins between the 从指定日期的startDate
and endDate
on the specified day will be counted. startDate
到endDate
之间开始的任何一周都将被计算在内。The week count is not bounded by calendar 周计数不受日历月或日历年的限制。month
or calendar year
.
When using an Olson Timezone Identifier in the 在<timezone>
field, MongoDB applies the DST offset if applicable for the specified timezone.<Timezone>
字段中使用Olson时区标识符时,MongoDB将应用DST偏移量(如果适用于指定的时区)。
For example, consider a 例如,考虑包含以下文档的sales
collection with the following document:sales
集合:
{ "_id" : 1, "item" : "abc", "price" : 20, "quantity" : 5, "date" : ISODate("2017-05-20T10:24:51.303Z") }
The following aggregation illustrates how MongoDB handles the DST offset for the Olson Timezone Identifier. 以下聚合说明了MongoDB如何处理Olson时区标识符的DST偏移量。The example uses the 该示例使用$hour
and $minute
operators to return the corresponding portions of the date
field:$hour
和$minute
运算符返回日期字段的相应部分:
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" } } } }])
The operation returns the following result:该操作返回以下结果:
{ "_id": 1, "nycHour" : 5, "nycMinute" : 24, "gmtHour" : 10, "gmtMinute" : 24, "nycOlsonHour" : 6, "nycOlsonMinute" : 24 }
The algorithm calculates the date difference using the Gregorian calendar.该算法使用公历计算日期差。
Leap years and daylight savings time are accounted for but not leap seconds.闰年和夏令时被计算在内,但不包括闰秒。
The difference returned can be negative.返回的差值可以是负数。
Create a collection of customer orders:创建客户订单集合:
db.orders.insertMany( [ { custId: 456, purchased: ISODate("2020-12-31"), delivered: ISODate("2021-01-05") }, { custId: 457, purchased: ISODate("2021-02-28"), delivered: ISODate("2021-03-07") }, { custId: 458, purchased: ISODate("2021-02-16"), delivered: ISODate("2021-02-18") } ] )
The following example:以下示例:
dateDiff
to calculate the difference between the purchased
date and the delivered
date.dateDiff
计算purchased
(购买)日期和delivered
(交付)日期之间的差异。db.orders.aggregate( [ { $group: { _id: null, averageTime: { $avg: { $dateDiff: { startDate: "$purchased", endDate: "$delivered", unit: "day" } } } } }, { $project: { _id: 0, numDays: { $trunc: [ "$averageTime", 1 ] } } } ] )
The $avg
accumulator in the $group
stage uses $dateDiff
on each document to get the time between the purchased
and delivered
dates. $group
阶段中的$avg
累加器在每个文档上使用$dateDiff
来获取购买日期和交付日期之间的时间。The resulting value is returned as 结果值作为averageTime
.averageTime
返回。
The decimal portion of the averageTime
is truncated ($trunc
) in the $project
stage to produce output like this:averageTime
的小数部分在$project
阶段被截断($trunc
),以生成如下输出:
{ "numDays" : 4.6 }
Create this collection with starting and ending dates for a subscription.使用订阅的开始和结束日期创建此集合。
db.subscriptions.insertMany( [ { custId: 456, start: ISODate("2010-01-01"), end: ISODate("2011-01-01") }, { custId: 457, start: ISODate("2010-01-01"), end: ISODate("2011-06-31") }, { custId: 458, start: ISODate("2010-03-01"), end: ISODate("2010-04-30") } ] )
The $dateDiff
expression returns a time difference expressed in integer units
. $dateDiff
表达式返回以整数单位表示的时间差。There are no fractional parts of a unit. 一个单位没有小数部分。For example, when counting in 例如,以年计算时,没有半年。years
there are no half years.
In this example, note how changing the 在本例中,请注意更改unit
changes the returned precision:unit
如何更改返回的精度:
db.subscriptions.aggregate( [ { $project: { Start: "$start", End: "$end", years: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "year" } }, months: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "month" } }, days: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "day" } }, _id: 0 } } ] )
The results are summarized in this table:结果总结如下表所示:
Start | End | Years | Months | Days |
---|---|---|---|---|
2010-01-01 | 2011-01-01 | 1 | 12 | 365 |
2010-01-01 | 2011-07-01 | 1 | 18 | 546 |
2010-03-01 | 2010-04-30 | 0 | 1 | 60 |
The count only increments when a new 该计数仅在新unit
starts, so 18 months are reported as 1 year in the second row and 60 days are reported as one month in the third row.unit
启动时递增,因此第二行中18个月报告为1年,第三行中60天报告为1个月。
Create a collection of months:创建月份集合:
db.months.insertMany( [ { month: "January", start: ISODate("2021-01-01"), end: ISODate("2021-01-31") }, { month: "February", start: ISODate("2021-02-01"), end: ISODate("2021-02-28") }, { month: "March", start: ISODate("2021-03-01"), end: ISODate("2021-03-31") }, ] )
You can change the start of each week, and count the resulting number of weeks in each month with the following code:您可以更改每周的开始时间,并使用以下代码计算每月的周数:
db.months.aggregate( [ { $project: { wks_default: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "week" } }, wks_monday: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "week", startOfWeek: "Monday" } }, wks_friday: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "week", startOfWeek: "fri" } }, _id: 0 } } ] )
The results are summarized in this table:结果总结如下表所示:
Month | Sunday | Monday | Friday |
---|---|---|---|
January | 5 | 4 | 4 |
February | 4 | 3 | 4 |
March | 4 | 4 | 4 |
From the results:从结果来看:
startOfWeek
is Sunday, the 5th week
in January, 2021 begins on the 31st.startOfWeek
是星期天时,第五周是2021年一月份,从31日开始。startDate
and endDate
, one week
is added to the count.startDate
和endDate
之间,所以计数加上一周。week
count is incremented even when a calendar week finishes after endDate
or in the next calendar period.endDate
之后或在下一个日历期间结束,周计数也会增加。