AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

$dateDiff(式 演算子)

$dateDiff

バージョン 5.0 の新機能。

2 つの日付の差を返します。

The $dateDiff expression has this syntax:

{
$dateDiff: {
startDate: <Expression>,
endDate: <Expression>,
unit: <Expression>,
timezone: <tzExpression>,
startOfWeek: <String>
}
}

$dateDiff calculates the difference by counting the upper boundaries of time intervals crossed from startDate to endDate within the timezone. The time intervals length is equal to one unit and are aligned so that their boundaries occur at integer multiples of unit along the time axis. It excludes partial units that do not cross a boundary. This expression returns an integer in the specified unit. If endDate precedes startDate, it returns a negative integer.

フィールド
必須/オプション
説明

startDate

必須

期間の始まり。startDate は、Date、Timestamp、または ObjectId に変換される任意の式にできます。

endDate

必須

期間の終了。endDate は、Date、Timestamp、または ObjectId に変換される任意の式にできます。

unit

必須

startDate と endDate の間の、時間測定の unit。これは以下の文字列に変換される式です。

  • year

  • quarter

  • week

  • month

  • day

  • hour

  • minute

  • second

  • millisecond

timezone

任意

操作を実行するタイムゾーン。<tzExpression> は、有効な式であり、Olson タイムゾーン識別子 または UTC オフセット として形式化された string に解決される必要があります。

  • Olsonタイムゾーン識別子:例:"America/New_York"、"Europe/London"、"GMT"

  • UTC オフセット: 例えば、"+04:45"、"-0530"、"+03"

timezone を省略すると、結果は UTC に表示されます。

startOfWeek

任意

単位が week と等しい場合に使用されます。デフォルトはSundayです。startOfWeek パラメータは、大文字と小文字を区別しない文字列に変換される式です。

  • monday (または mon)

  • tuesday (または tue)

  • wednesday (または wed)

  • thursday (または thu)

  • friday (または fri)

  • saturday (または sat)

  • sunday (または sun)

$dateDiff式は、各日付の特定の部分を比較することで整数を返します。year単位の場合、年の値が比較されます。2022のどの日付も2023のどの日付ともyearだけ離れています。week単位の場合、週番号が比較されます。第5週のどの日付も第6週のどの日付ともweekだけ離れています。

$dateDiff counts the unit boundaries crossed between startDate and endDate. It does not measure elapsed duration. For example, $dateDiff reports a difference of one year between December 31, 2022 and January 1, 2023. A year boundary was crossed, even though a few hours passed between the two dates. See Year Boundary Crossing for a full example.

startOfWeek パラメータによって変更されない限り、week は Sunday から始まります。$dateDiff は、指定された日の startDate と endDate の間に始まるすべての週をカウントします。週数は暦上の month または year によって制限されません。

<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 がタイムゾーン識別子の 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.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")
}
]
)

次の例:

  • 配達にかかる平均日数を返します。

  • 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 ]
}
}
}
]
)

$group ステージの$avg アキュムレータでは、purchased の日付からdelivered の日付までの期間の取得に $dateDiff を使用します。結果の値は averageTime として返されます。

averageTime の小数点以下の値は $project ステージで切り捨てられ($trunc)、下記のような出力が生成されます。

{ "numDays" : 4.6 }

サブスクリプションの開始日と終了日を指定してこのコレクションを作成します。

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")
}
]
)

$dateDiff 式は、整数 units で表された期間の差を返します。単位には小数部分はありません。たとえば years でカウントする場合、半年の単位はありません。

この例では 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
}
}
]
)

結果を次の表にまとめています。

始める
End
年
か月
日

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

2 行目では、2010-01-01 と 2011-07-01 は年が異なります(2010 と 2011)。したがって、$dateDiff は 1 year を返します。3 行目では、2010-03-01 (3 月)と 2010-04-30 (4 月)は 1 か月異なります。したがって、$dateDiff は 1 month を返します。

数時間しか離れていないが、暦年の境界の両側にある 2 つの日付を持つコレクションを作成します。

db.events.insertOne(
{
start: ISODate("2022-12-31T20:00:00Z"),
end: ISODate("2023-01-01T02:00:00Z")
}
)

year 単位の $dateDiff を使用して、2 つの日付の間の違いを検出します。

db.events.aggregate(
[
{
$project: {
_id: 0,
yearsApart: {
$dateDiff: {
startDate: "$start",
endDate: "$end",
unit: "year"
}
}
}
}
]
)

この操作では、次の結果を返します。

{ "yearsApart" : 1 }

2つの日付の間に6時間しか経っていないにもかかわらず、日付が異なる暦年に属するため、$dateDiffは1を返します。これは、$dateDiffが経過時間ではなく、単位の境界を超えた回数をカウントすることを示しています。

月のコレクションを作成します。

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")
},
]
)

以下のコードを使用して、各週の始まりを変更した上で、各月の週数をカウントできます。

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
}
}
]
)

結果を次の表にまとめています。

月
Sunday
Monday
Friday

1月

5

4

4

2月

4

3

4

3月

4

4

4

結果より:

  • startOfWeek が日曜日の場合、2021 年 1 月の第 5 週 (week) は31日から始まります。

  • 31日は日曜日で、 startDate から endDateの間であるため、カウントに 1 week が追加されます。

  • 暦上の週が endDate 以降、または暦上の次の期間内に終了する場合でも、week カウントは増加します。

このページを評価

項目一覧