On this page本页内容
$dateAdd
New in version 5.0.在5.0版中新增。
Increments a Date object by a specified number of time units.按指定的时间单位递增Date对象。
The $dateAdd expression has the following syntax:$dateAdd表达式具有以下语法:
{
   $dateAdd: {
      startDate: <Expression>,
      unit: <Expression>,
      amount: <Expression>,
      timezone: <tzExpression>
   }
}
Returns a Date. 返回一个Date。The startDate can be any expression that resolves to type Date, Timestamp or ObjectId. startDate可以是解析为类型Date、Timestamp或ObjectId的任何表达式。No matter which data type is used as input, the value returned will be a Date object.无论使用哪种数据类型作为输入,返回的值都将是Date对象。
| startDate | startDatecan be any expression that resolves to a Date, a Timestamp, or an ObjectID.startDate可以是解析为日期、时间戳或ObjectID的任何表达式。 | |||||||
| unit | 
 
 | |||||||
| amount | unitsadded to thestartDate.startDate的单位数。amountis an expression that resolves to an integer or long.amount是一个解析为整数或long的表达式。amountcan also resolve to an integral decimal or a double if that value can be converted to a long without loss of precision. | |||||||
| timezone | 
 
 | 
For more information on expressions and types see Expressions and BSON Types.有关表达式和类型的更多信息,请参阅表达式和BSON类型。
MongoDB follows prevaling database usage and works with time in UTC. MongoDB遵循预先记录的数据库使用情况,并以UTC为单位处理时间。The dateAdd expression always takes a startDate in UTC and returns a result in UTC. dateAdd表达式始终采用UTC格式的startDate,并以UTC格式返回结果。If the 如果指定了timezone is specified, the calculation will be done using the specified timezone. timezone,将使用指定的timezone进行计算。The timezone is especially important when a calculation involves Daylight Savings Time (DST).当计算涉及夏令时(DST)时,时区尤其重要。
If the 如果unit is a month, or larger the operation adjusts to account for the last day of the month. unit为month或更大,则该操作会调整到该月的最后一天。Adding one 例如,在10月的最后一天加上一个月,说明了“本月的最后一天”的调整。month on the last day of October, for example, demonstrates the "last-day-of-the-month" adjustment.
{
   $dateAdd:
      {
         startDate: ISODate("2020-10-31T12:10:05Z"),
         unit: "month",
         amount: 1
      }
}
Notice that the date returned, 请注意,返回的日期ISODate("2020-11-30T12:10:05Z"), is the 30th and not the 31st since November has fewer days than October.ISODate("2020-11-30T12:10:05Z")是第30天,而不是第31天,因为11月的天数少于10月。
When using an Olson Timezone Identifier in the 在<timezone> field, MongoDB applies the DST offset if applicable for the specified timezone.<Timezone>字段中使用奥尔森时区标识符时,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运算符返回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" }
       }
   }
}])
The operation returns the following result:该操作返回以下结果:
{
   "_id": 1,
   "nycHour" : 5,
   "nycMinute" : 24,
   "gmtHour" : 10,
   "gmtMinute" : 24,
   "nycOlsonHour" : 6,
   "nycOlsonMinute" : 24
}
Consider a collection of customer orders with these documents:考虑客户订单与这些文件的集合:
db.shipping.insertMany(
  [
     { custId: 456, purchaseDate: ISODate("2020-12-31") },
     { custId: 457, purchaseDate: ISODate("2021-02-28") },
     { custId: 458, purchaseDate: ISODate("2021-02-26") }
  ]
)
The normal shipping time is 3 days. 正常装运时间为3天。You can use 您可以在聚合管道中使用$dateAdd in an aggregation pipeline to set an expectedDeliveryDate 3 days in the future.$dateAdd来设置未来3天的expectedDeliveryDate。
db.shipping.aggregate(
   [
      {
         $project:
            {
               expectedDeliveryDate:
                  {
                     $dateAdd:
                        {
                           startDate: "$purchaseDate",
                           unit: "day",
                           amount: 3
                        }
                  }
            }
       },
       {
          $merge: "shipping"
       }
    ]
 )
After adding 3 days to the 在purchaseDate with $dateAdd in the $project stage, the $merge stage updates the original documents with the expectedDeliveryDate.$project阶段使用$dateAdd向purchaseDate添加3天之后,$merge阶段使用expectedDeliveryDate更新原始文档。
The resulting documents look like this:生成的文档如下所示:
{
   "_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")
}
Update the 使用以下代码更新上一个示例中的shipping collection from the last example with this code to add delivery dates to the documents: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" ) } }
)
You want to find late shipments. 你想找到迟交的货物。Use 在$dateAdd in a $match stage to create a filter that matches documents in a range of dates defined by a starting point ($purchaseDate) and a time period given by $dateAdd.$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"
                         }
                   }
             }
       }
   ]
)
The $match stage uses $gt and $dateAdd in an expression ($expr) to compare the actual deliveryDate with an expected date. $match阶段在表达式($expr)中使用$gt和$dateAdd来比较实际交付日期和预期日期。Documents with delivery dates more than 5 days after the 交付日期在purchaseDate are passed on to the $project stage.purchaseDate后超过5天的文档将传递到$project阶段。
The $project stage uses the $dateToString expression to convert the dates to a more readable format. $project阶段使用$dateToString表达式将日期转换为更可读的格式。Without the conversion, MongoDB would return the date in ISODate format.如果没有转换,MongoDB将以ISODate格式返回日期。
In this example only one record is returned:在本例中,只返回一条记录:
{ "custId" : 456, "purchased" : "2020-12-31", "delivery" : "2021-01-10" }
All dates are stored internally in UTC time. 所有日期都存储在UTC时间内。When a 如果指定了timezone is specified, $dateAdd uses local time to carry out the calculations. timezone,$dateAdd使用本地时间执行计算。The results are displayed in UTC.结果以UTC显示。
You have customers in several timezones and you want to see what effect daylight savings time might have on your billing periods if you bill by 你有几个时区的客户,如果你按天或按小时计费,你想看看夏令时对你的计费周期有什么影响。day or by hour.
Create this collection of connection times:创建此连接时间集合:
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")
      }
   ]
)
First add 1 day, then add 24 hours to the 首先在每个文档中添加1天,然后在登录日期上添加24小时。login dates in each document.
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()
The $dateToString expression reformats the output for readability. $dateToString表达式重新设置输出的可读性。Results are summarized here:结果总结如下:
| New York | Mexico City | |
|---|---|---|
| Start | 2021-03-13 15:00 | 2021-03-13 10:00 | 
| Start, TZ Info | 2021-03-13 10:00 | 2021-03-13 04:00 | 
| 1 Day | 2021-03-14 14:00 | 2021-03-14 10:00 | 
| 1 Day, TZ Info | 2021-03-14 10:00 | 2021-03-14 04:00 | 
| 24 Hours | 2021-03-14 15:00 | 2021-03-14 10:00 | 
| 24 Hours, TZ Info | 2021-03-14 11:00 | 2021-03-14 04:00 | 
The chart highlights several points:图表突出了几点:
$login for New York is UTC -5, however the start, days, and hours rows display the time in UTC.$login是UTC-5,但是start、days和hours行以UTC显示时间。day to the next.day, not the hour. hours. hours内没有DST变化。unit is day or larger and the computation crosses a clock change in the specified timezone.unit为day或更大且计算跨越指定时区内的时钟变化时,仅对DST进行调整。