$dateSubtract is a MongoDB aggregation expression that subtracts a number of time units from a date and returns a new BSON Date. Use it for reminders, cutoffs, and “N days before” logic (MongoDB 5.0+).
Remember
$dateSubtract = move a date backward
{ $dateSubtract: {
startDate: <date>, // required
unit: <string>, // required e.g. "day"
amount: <number>, // required e.g. 7
timezone: <string> // optional
}
}
units → year, quarter, week, month, day,
hour, minute, second, millisecond
returns → a new Date (original field unchanged)
Set startDate to a Date field (or Date expression).
Set unit (for example "day") and amount (for example 7).
Optionally set timezone when calendar math should follow a local zone.
Piece
Required?
Role
startDate
Yes
Date / Timestamp / ObjectId to move from
unit
Yes
Time unit string ("day", "hour", …)
amount
Yes
How many units to subtract
timezone
No
Local calendar math (DST-aware)
Pseudocode
Pseudocode
for each document:
d = evaluate(startDate)
u = evaluate(unit)
n = evaluate(amount)
if d is null or missing:
result = null
else:
result = d minus n units of type u
emit { ..., field: result }
Reference
Cheat Sheet
Keep these facts handy while writing date-subtraction expressions.
An event starts on 2026-10-02T09:15:00Z. We want a reminder date exactly 7 days earlier.
Calculation
Document:
{ starts_at: ISODate("2026-10-02T09:15:00.000Z") }
$dateSubtract: {
startDate: "$starts_at",
unit: "day",
amount: 7
}
Step by step:
1) Read starts_at → 2026-10-02 09:15 UTC
2) Subtract 7 days
3) Keep the same time of day
Result:
ISODate("2026-09-25T09:15:00.000Z")
Check: Oct 2 minus 7 days = Sep 25 ✓
Code
MongoDB Examples
We use one event with a start time. First we store it, then we subtract days for a reminder, then we subtract hours. Run these in mongosh after inserting the sample data once.
Example 1 — Sample Data
Imagine one event named Launch that starts at 2026-10-02 09:15 UTC. We save that Date in a collection named events.
Timeline:
reminder? starts_at
| |
----+------------------+----> time
←── 7 days ──→
Next examples:
• subtract 7 days → reminder date
• subtract 2 hours → two hours before start
How It Works
Insert once.insertOne adds a single event document to events.
Store a real Date.ISODate(...) creates a BSON Date, not a string.
find() shows the same shape. What you inserted is what you get back—ready for $dateSubtract next.
Example 2 — Subtract Days
Goal: compute a reminder date 7 days beforestarts_at.
Same stored document. Still using starts_at from Example 1.
Change only the unit and amount."hour" and 2 instead of "day" and 7.
Move the clock.09:15 becomes 07:15 on the same calendar day.
Easy check. Two hours earlier than 09:15 is 07:15.
Edge Cases & Pitfalls
Check these before using $dateSubtract in production pipelines.
type
startDate must be a Date
String dates will not work until you parse them with $dateFromString (or store real Dates).
diff
Not the same as $dateDiff
$dateSubtract returns a Date. If you need “how many days between A and B?”, use $dateDiff.
tz
Timezone matters near DST
For day/month/year math around daylight saving changes, set timezone so the calendar step matches local rules.
null
Null startDate becomes null
Missing or null dates return null, not an error. Filter or fill them before date math if nulls are invalid.
Analysis
Performance Notes
Approach
Cost
Best for
$dateSubtract alone
Per-document date math
Reminders, cutoffs, lead times
+ timezone
Slightly heavier calendar work
Local-day rules / DST edges
Compute once, store result
Write cost, cheaper later reads
Fields reused in many queries
Date arithmetic is cheap compared with large sorts or joins. Filter early with $match when only some documents need a computed date.
Remember
Key Takeaways
Role: subtract time units → new BSON Date.
Inputs:startDate, unit, and amount.
Pair: reverse direction of $dateAdd; not a count like $dateDiff.
Pattern:unit: "day", amount: 7 for “one week before”.
One line:$dateSubtract answers “what date is N units before this one?”—and returns a Date.
Frequently Asked Questions
$dateSubtract subtracts a number of time units from a date and returns a new BSON Date. Use it for rolling cutoffs, grace-period starts, or past deadlines inside aggregation pipelines (MongoDB 5.0+).
Use { $dateSubtract: { startDate: <date>, unit: <string>, amount: <number>, timezone: <string> } }. startDate, unit, and amount are required. timezone is optional.
year, quarter, week, month, day, hour, minute, second, and millisecond. Pass the unit as a string such as "day" or "hour".
$dateSubtract moves a date backward. $dateAdd moves it forward. Both return a new BSON Date, not a number of days.
$dateSubtract returns a new date. $dateDiff returns how many units lie between two dates (a number).
No. It computes a new Date in the pipeline result. Your original field stays unchanged unless you write the result back with an update.