$dateDiff is a MongoDB aggregation expression that returns how many time units separate two dates. The result is a truncated integer (whole units only). If endDate is earlier, the result is negative.
Remember
$dateDiff = whole units between start and end
{
$dateDiff: {
startDate: <date>,
endDate: <date>,
unit: "<unit>",
timezone: "<tz>", // optional
startOfWeek: "<day>" // optional (week)
}
}
units: year, quarter, month, week, day,
hour, minute, second, millisecond
partial units → truncated (not rounded up)
null date → null
Set startDate and endDate to Date fields or expressions.
Set unit (for example "day" or "hour").
Optionally set timezone or startOfWeek when those boundaries matter.
Piece
Required?
Role
startDate
Yes
Beginning of the interval
endDate
Yes
End of the interval
unit
Yes
What to count (day, hour, month, …)
timezone / startOfWeek
No
Boundary rules for some units
Pseudocode
Pseudocode
for each document:
start = evaluate(startDate)
end = evaluate(endDate)
unit = evaluate(unit)
if start or end is null or missing:
result = null
else:
result = truncated whole units from start to end
// negative if end < start
emit { ..., field: result }
Reference
Cheat Sheet
Keep these facts handy while measuring date gaps.
Topic
Detail
Type
Aggregation expression (not a find filter)
Syntax
{ $dateDiff: { startDate, endDate, unit } }
Result
Truncated integer (whole units)
Negative
When endDate < startDate
vs $dateAdd
Diff → number; Add → new date
Common units
day, hour, month, week
Sample check
2026-01-10 → 2026-01-17 = 7 days
Try it
Live Preview
Watch $dateDiff count whole days or hours between two loan dates.
Simulates $dateDiff from start date 2026-01-10 (UTC midnight).
Same stored document. Still using Jan 10 → Jan 17 from Example 1.
Change only the unit.unit: "hour" counts hours instead of days.
Easy check. 7 days × 24 hours = 168.
Edge Cases & Pitfalls
Check these before using $dateDiff in production pipelines.
trunc
Partial units are truncated
A 23-hour gap with unit: "day" returns 0. Use a finer unit when fractions matter.
order
End before start → negative
Swap dates if you always want a positive duration, or take the absolute value afterward.
vs subtract
Not the same as $subtract
$subtract on two dates returns milliseconds. Prefer $dateDiff for day/month/hour counts.
null
Null dates stay null
If either date is missing or null, the result is null. Validate both sides before measuring.
Analysis
Performance Notes
Approach
Cost
Best for
$dateDiff per document
Cheap date math
Durations, SLAs, loan lengths
Diff then $match
Compute on scanned docs
Filter after computing a duration
Store duration on write
No recompute on read
Hot queries on the same gap
Date diffs are cheap compared with large sorts or joins. Filter early with $match when only some documents need a duration.
Remember
Key Takeaways
Role: count whole units between two dates.
Required:startDate, endDate, unit.
Result: truncated integer; can be negative.
Sibling: use $dateAdd when you need a new date, not a count.
One line:$dateDiff answers “how many whole units between these two dates?”
Frequently Asked Questions
$dateDiff returns how many time units separate two dates—for example days between borrowedOn and returnedOn. Use it inside aggregation stages such as $project and $addFields.
Use { $dateDiff: { startDate: <date>, endDate: <date>, unit: <string>, timezone: <tz>, startOfWeek: <string> } }. startDate, endDate, and unit are required.
Supported units include year, quarter, month, week, day, hour, minute, second, and millisecond. Pass the unit as a string such as "day" or "hour".
$dateDiff measures the gap between two dates and returns a number. $dateAdd adds units to one date and returns a new date.
Yes. If endDate is earlier than startDate, $dateDiff returns a negative number.
No. $dateDiff returns a truncated integer—only whole units count. Less than one full day with unit "day" returns 0.