MongoDB $dateSubtract Operator

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

What Is $dateSubtract?

$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)
UsePrefer
Move a date backward$dateSubtract
Move a date forward$dateAdd
Count units between two dates$dateDiff

How to Use $dateSubtract in MongoDB

Pick the start date, choose a unit, then say how many units to subtract.

  1. Choose an expression stage ($addFields or $project).
  2. Set startDate to a Date field (or Date expression).
  3. Set unit (for example "day") and amount (for example 7).
  4. Optionally set timezone when calendar math should follow a local zone.
PieceRequired?Role
startDateYesDate / Timestamp / ObjectId to move from
unitYesTime unit string ("day", "hour", …)
amountYesHow many units to subtract
timezoneNoLocal 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 }

Cheat Sheet

Keep these facts handy while writing date-subtraction expressions.

TopicDetail
TypeAggregation expression (MongoDB 5.0+)
Syntax{ $dateSubtract: { startDate, unit, amount } }
ReturnsA new BSON Date
Common units"day", "hour", "week", "month", "year"
7-day patternunit: "day", amount: 7
Forward twin$dateAdd
Sample check2026-10-02 minus 7 days → 2026-09-25

Live Preview

Watch $dateSubtract move a start date backward by days or hours.

Simulates $dateSubtract from ISODate("2026-10-02T09:15:00.000Z").

Result
startDate = ISODate("2026-10-02T09:15:00.000Z")
unit = "day", amount = 7

$dateSubtract → ISODate("2026-09-25T09:15:00.000Z")

{ reminder_at: ISODate("2026-09-25T09:15:00.000Z") }

Worked Walkthrough — 7 Days Before

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 ✓

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.

mongosh
db.events.insertOne({
  _id: 1,
  title: "Launch",
  starts_at: ISODate("2026-10-02T09:15:00.000Z")
});

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps one document in events. Run find() to see it:

mongosh
db.events.find()

Read that document like this:

Field in MongoDBValuePlain English
_id1Document id (row number for this lesson)
title"Launch"Event name
starts_atISODate("2026-10-02T09:15:00.000Z")Start time (real Date, not a string)
Picture
Timeline:

  reminder?          starts_at
      |                  |
  ----+------------------+----> time
      ←── 7 days ──→

Next examples:
  • subtract 7 days  → reminder date
  • subtract 2 hours → two hours before start

How It Works

  1. Insert once. insertOne adds a single event document to events.
  2. Store a real Date. ISODate(...) creates a BSON Date, not a string.
  3. 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 before starts_at.

mongosh
db.events.aggregate([
  {
    $addFields: {
      reminder_at: {
        $dateSubtract: {
          startDate: "$starts_at",
          unit: "day",
          amount: 7
        }
      }
    }
  }
]);

How It Works

  1. Read the stored Date. MongoDB already has starts_at from Example 1.
  2. Choose the unit. unit: "day" means calendar days, not a raw millisecond guess.
  3. Subtract 7. October 2 becomes September 25; the time of day stays 09:15.
  4. Keep all fields. $addFields adds reminder_at next to starts_at—nothing is deleted.

Example 3 — Subtract Hours

Same event, but subtract 2 hours for a shorter lead time.

mongosh
db.events.aggregate([
  {
    $addFields: {
      warmup_at: {
        $dateSubtract: {
          startDate: "$starts_at",
          unit: "hour",
          amount: 2
        }
      }
    }
  }
]);

How It Works

  1. Same stored document. Still using starts_at from Example 1.
  2. Change only the unit and amount. "hour" and 2 instead of "day" and 7.
  3. Move the clock. 09:15 becomes 07:15 on the same calendar day.
  4. 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.

Performance Notes

ApproachCostBest for
$dateSubtract alonePer-document date mathReminders, cutoffs, lead times
+ timezoneSlightly heavier calendar workLocal-day rules / DST edges
Compute once, store resultWrite cost, cheaper later readsFields 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.

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.

Next: $dateToParts

Break a Date into year, month, day, hour, and more.

$dateToParts tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful