定義
$dateAddバージョン 5.0 で追加
指定された時間単位数の分だけ Dateオブジェクトを増加させます。
$dateAdd式の構文は次のとおりです。{ $dateAdd: { startDate: <Expression>, unit: <Expression>, amount: <Expression>, timezone: <tzExpression> } } Dateを返します。
startDateは、Date 型、Timestamp 型、または ObjectId 型に変換される任意の式にできます。 どのデータ型が入力に使用されるかにかかわらず、返される値はDateオブジェクトになります。フィールド必須/オプション説明startDate必須
unit必須
unitは、startDateに追加された時間のamountを測定するために使用されます。unitは、次のいずれかの文字列に変換される式です。yearquarterweekmonthdayhourminutesecondmillisecond
amount必須
startDateに追加されたunitsの数。amountは、integer または long に変換される式です。amountは、その値が精度を失うことなく long に変換できる場合は、integer decimal または double に変換することもできます。timezone任意
操作を実行するタイムゾーン。
<tzExpression>は、有効な式であり、Olson タイムゾーン識別子 または UTC オフセット のいずれかとして形式された文字列に変換される必要があります。timezoneが指定されていない場合、結果はUTCに表示されます。形式例Olson タイムゾーン識別子
"America/New_York" "Europe/London" "GMT" UTC オフセット
+/-[hh]:[mm], e.g. "+04:45" +/-[hh][mm], e.g. "-0530" +/-[hh], e.g. "+03" 式とタイプの詳細については、「式とBSON types 」を参照してください。
動作
時間測定
MongoDB は一般的なデータベースの使用法に従い、UTC の時間で動作します。dateAdd式は常に UTC のstartDateを受け取り、UTC で結果を返します。 timezoneが指定されている場合は、指定されたtimezoneを使用して計算が行われます。 計算に夏時間 (DST) が含まれる場合、タイムゾーンは特に重要です。
unit が month またはそれより大きい場合、操作は月の最終日を考慮して調整されます。たとえば、10 月の最終日に month を 1 つ足すと、「月末日」の調整が行われます。
{ $dateAdd: { startDate: ISODate("2020-10-31T12:10:05Z"), unit: "month", amount: 1 } }
11 月は 10 月よりも日数が少ないため、返される日付 ISODate("2020-11-30T12:10:05Z") は 31 日ではなく 30 日であることに注意してください。
タイムゾーン
<timezone> フィールドで Olson タイムゾーン識別子を使用する際、指定されたタイムゾーンに該当する場合、MongoDB は DST オフセットを適用します。
たとえば、次のドキュメントを含む sales コレクションを考えます。
{ "_id" : 1, "item" : "abc", "price" : 20, "quantity" : 5, "date" : ISODate("2017-05-20T10:24:51.303Z") }
次の集計は、MongoDB がタイムゾーン識別子の 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 ステージでは、$gt と $dateAdd を式($expr)で使用して、実際の deliveryDate と予想される日付を比較します。purchaseDate から配達日が 5 日以上経過したドキュメントは、$project ステージに渡されます。
$projectステージでは、$dateToString 式を使用して日付をより読みやすい形式に変換します。変換を行わない場合、MongoDB は日付を ISODate 形式で返します。
この例では、1 つのレコードのみが返されます。
{ "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 |
スタート、タイムゾーン情報 | 2021-03-13 10:00 | 2021-03-13 04:00 |
1 日 | 2021-03-14 14:00 | 2021-03-14 10:00 |
1 日、タイムゾーン情報 | 2021-03-14 10:00 | 2021-03-14 04:00 |
24 時間 | 2021-03-14 15:00 | 2021-03-14 10:00 |
24 時間、タイムゾーン情報 | 2021-03-14 11:00 | 2021-03-14 04:00 |
このチャートには、いくつかの重要なポイントがあります。
書式設定されていない日付は UTC で返されます。ニューヨークの
$loginは UTC -5 ですが、start行、days行、およびhours行には時刻が UTC で表示されます。3 月 14 日はニューヨークでは夏時間の開始日ですが、メキシコでは違います。計算された時間は、ロケーションが DST に切り替わり、ある
dayから次の日に移るときに調整されます。DST は、
hourではなく、dayの長さを変更します。hoursでは、DST の変更はありません。DST の調整は、測定unitがday以上で、計算が指定されたtimezoneで時差が生じる場合にのみ行われます。