MongoDB $dateSubtract Operator

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 4 Examples
Date Operations

What You’ll Learn

The $dateSubtract operator subtracts time units from a date inside MongoDB aggregation pipelines. Use it to compute rolling cutoffs, grace-period starts, retention windows, or any past timestamp relative to a stored date or $$NOW.

01

Date Arithmetic

Subtract units from dates.

02

Syntax

startDate, unit, amount.

03

Time Units

day, hour, year, etc.

04

Timezone

Optional IANA zone.

05

Use Cases

Cutoffs, grace periods.

06

vs $dateAdd

Subtract vs add.

Definition and Usage

In MongoDB’s aggregation framework, the $dateSubtract operator decrements a startDate by a given amount of unit values and returns the resulting BSON date. For example, subtracting 30 days from $$NOW gives you the cutoff for “active in the last 30 days” queries.

💡
Beginner Tip

$dateSubtract returns a Date, not a number. It mirrors $dateAdd but moves backward in time. Requires MongoDB 5.0+ and a valid BSON date for startDate.

📝 Syntax

The $dateSubtract operator takes an object with at least three fields:

mongosh
{
  $dateSubtract: {
    startDate: <dateExpression>,
    unit: <string>,
    amount: <numberExpression>,
    timezone: <string>
  }
}

Syntax Rules

  • startDate — the base date (field reference, $$NOW, or literal).
  • unit — one of: year, quarter, week, day, hour, minute, second, millisecond.
  • amount — how many units to subtract (positive integer or expression).
  • timezone — optional Olson timezone ID (e.g. "America/New_York").
  • Use inside $project, $addFields, $set, or update aggregation pipelines.
  • Prefer $dateSubtract over $dateAdd with a negative amount for readable backward date math.

💡 $dateSubtract vs $dateAdd vs $dateDiff

$dateSubtract — startDate − N units → new date
$dateAdd — startDate + N units → new date
$dateDiff — two dates → number of units between them

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (date)
Required fieldsstartDate, unit, amount
Return typeBSON Date
Supported unitsyear, quarter, week, day, hour, minute, second, millisecond
MongoDB version5.0+
Subtract 7 days
{
  $dateSubtract: {
    startDate: "$dueDate",
    unit: "day",
    amount: 7
  }
}

One week earlier

30-day cutoff
{
  $dateSubtract: {
    startDate: "$$NOW",
    unit: "day",
    amount: 30
  }
}

Rolling window start

Subtract 1 year
{
  $dateSubtract: {
    startDate: "$reportDate",
    unit: "year",
    amount: 1
  }
}

Same date last year

With timezone
{
  $dateSubtract: {
    startDate: "$start",
    unit: "day",
    amount: 1,
    timezone: "UTC"
  }
}

Timezone-aware subtract

Examples Gallery

Compute grace-period reminders, rolling activity cutoffs, and timezone-aware past dates with $dateSubtract.

📚 Subtract Days from a Due Date

Use an invoices collection and compute a reminder date seven days before payment is due.

Sample Input Documents

Suppose you have an invoices collection with a dueDate field:

mongosh
[
  {
    "_id": ObjectId("609c26812e9274a86871bc6a"),
    "customer": "Acme Corp",
    "dueDate": ISODate("2024-06-15T00:00:00Z")
  },
  {
    "_id": ObjectId("609c26812e9274a86871bc6b"),
    "customer": "Globex",
    "dueDate": ISODate("2024-07-01T00:00:00Z")
  }
]

Example 1 — Reminder Date 7 Days Before Due

Subtract 7 days from dueDate to get when to send a payment reminder:

mongosh
db.invoices.aggregate([
  {
    $project: {
      customer: 1,
      dueDate: 1,
      reminderDate: {
        $dateSubtract: {
          startDate: "$dueDate",
          unit: "day",
          amount: 7
        }
      }
    }
  }
])

How It Works

  • $dateSubtract moves the date backward by exactly 7 calendar days.
  • Acme: June 15 minus 7 days = June 8 reminder.
  • The result is a BSON Date suitable for scheduled jobs or $match filters.

📈 Practical Patterns

Rolling windows, year-over-year comparisons, and filtering recent activity.

Example 2 — 30-Day Rolling Cutoff from Now

Subtract 30 days from the current time to define the start of a “last 30 days” window:

mongosh
db.users.aggregate([
  {
    $addFields: {
      activeSinceCutoff: {
        $dateSubtract: {
          startDate: "$$NOW",
          unit: "day",
          amount: 30
        }
      }
    }
  },
  {
    $project: {
      name: 1,
      lastLogin: 1,
      activeSinceCutoff: 1
    }
  }
])

// activeSinceCutoff = date 30 days before pipeline runs

How It Works

$$NOW is evaluated when the pipeline runs. Subtracting days gives a fixed cutoff you can compare against lastLogin or other activity timestamps.

Example 3 — Same Date One Year Ago

Subtract one year for year-over-year reporting:

mongosh
db.sales.aggregate([
  {
    $project: {
      region: 1,
      reportDate: 1,
      priorYearDate: {
        $dateSubtract: {
          startDate: "$reportDate",
          unit: "year",
          amount: 1
        }
      }
    }
  }
])

// reportDate: 2024-03-15 → priorYearDate: 2023-03-15

How It Works

The year unit handles calendar-year arithmetic, including leap-year edge cases (Feb 29 maps appropriately). Use the result to join or compare against historical data.

Example 4 — Filter Users Active in the Last 7 Days

Combine $dateSubtract with $match to find recently active users:

mongosh
db.users.aggregate([
  {
    $match: {
      lastLogin: {
        $gte: {
          $dateSubtract: {
            startDate: "$$NOW",
            unit: "day",
            amount: 7
          }
        }
      }
    }
  },
  {
    $project: {
      name: 1,
      lastLogin: 1
    }
  }
])

How It Works

MongoDB 5.0+ allows aggregation expressions inside $match when using the aggregation pipeline form of find or in $match after $addFields. Compute the cutoff once, then keep documents where lastLogin is on or after that date.

🚀 Use Cases

  • Payment reminders — subtract days from due dates to schedule notifications.
  • Retention windows — define “active in last N days” cutoffs from $$NOW.
  • Year-over-year analysis — subtract years from report dates for historical comparison.
  • Data archival — identify records older than a threshold by subtracting from current time.

🧠 How $dateSubtract Works

1

MongoDB resolves startDate

The base date is evaluated per document — a field, $$NOW, or literal ISODate.

Input
2

$dateSubtract removes the units

MongoDB subtracts amount of unit, optionally respecting timezone.

Subtract
3

The new date is returned

The earlier timestamp is stored in the field you define — ready for filtering or display.

Output
=

A date in the past

Use in $match range queries, reminders, YoY joins, or alongside $dateAdd for bidirectional date math.

Conclusion

The $dateSubtract operator is the clearest way to perform backward date arithmetic in MongoDB aggregation pipelines. With explicit unit and amount fields, it replaces negative $dateAdd calls and manual millisecond subtraction for most business rules.

Pair it with $dateAdd for forward shifts and $dateDiff when you need the distance between two dates as a number. Always confirm your MongoDB version is 5.0+ and that startDate fields are proper BSON dates.

💡 Best Practices

✅ Do

  • Use $dateSubtract instead of negative $dateAdd for clarity
  • Store dates as BSON Date type, not strings
  • Use timezone when local calendar rules matter
  • Pick the right unit (day vs hour vs year)
  • Test edge cases around leap years and DST boundaries

❌ Don’t

  • Use $dateSubtract on MongoDB versions before 5.0
  • Pass invalid unit strings (no month unit exists)
  • Confuse $dateSubtract with $dateDiff
  • Forget to convert string dates with $dateFromString first
  • Assume subtracting days always equals 24 × N hours (calendar vs fixed duration)

Key Takeaways

Knowledge Unlocked

Five things to remember about $dateSubtract

Use these points when subtracting time from dates in MongoDB.

5
Core concepts
📝 02

Three Fields

startDate, unit, amount.

Syntax
🛠 03

Date Output

Not a number.

Output
🌐 04

Timezone

Optional Olson ID.

Option
05

Mirror of $dateAdd

Subtract vs add.

Important

❓ Frequently Asked Questions

$dateSubtract subtracts a specified number of time units from a date and returns the new date. Use it to compute rolling cutoffs, grace-period starts, or past deadlines inside aggregation pipelines.
{ $dateSubtract: { startDate: <date>, unit: <string>, amount: <number>, timezone: <string> } }. startDate, unit, and amount are required — the same shape as $dateAdd, but units are subtracted instead of added.
year, quarter, week, day, hour, minute, second, and millisecond. Pass the unit as a string such as "day" or "hour". There is no "month" unit.
$dateSubtract moves a date backward in time by subtracting units from startDate. $dateAdd moves it forward. Both return a new BSON Date, not a number.
$dateSubtract is available in MongoDB 5.0 and later in aggregation pipelines and update pipelines that use aggregation expressions.

Continue the Operator Series

Move on to $dateToParts to split dates into components, or review $dateAdd for forward date math.

Next: $dateToParts →

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.

5 people found this page helpful