MongoDB $month Operator

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

What You’ll Learn

The $month operator extracts the month (1–12) from a BSON Date inside MongoDB aggregation pipelines. Use it for seasonal sales reports, monthly dashboards, quarter filters, and year-over-year month comparisons.

01

Extract Month

Date → 1–12.

02

Syntax

One date argument.

03

1-Based

Jan=1, Dec=12.

04

Timezone Option

Local month support.

05

Use Cases

Sales, seasons.

06

Related Ops

$year, $dayOfMonth.

Definition and Usage

In MongoDB’s aggregation framework, the $month operator takes a date expression and returns an integer from 1 to 12. For example, $month applied to ISODate("2024-06-15T14:30:00Z") returns 6 (June), and ISODate("2024-12-31T23:59:59Z") returns 12 (December).

Unlike JavaScript’s Date.getMonth(), which is 0-based (January = 0), MongoDB’s $month is 1-based. January is always 1 and December is always 12.

💡
Beginner Tip

$month uses UTC by default. For seasonal business rules in local time (e.g., fiscal calendars), use the object form with a timezone option.

📝 Syntax

The $month operator takes a date expression, or an object with date and timezone:

mongosh
{ $month: <dateExpression> }

// With timezone:
{
  $month: {
    date: <dateExpression>,
    timezone: <tz>
  }
}

Syntax Rules

  • Argument — any expression that evaluates to a BSON Date (field, $$NOW, or literal).
  • Return value — integer from 1 to 12 (January = 1, December = 12).
  • Null input — returns null when the date is null or missing.
  • Timezone — optional; use Olson timezone IDs like "America/New_York".
  • Use inside $project, $addFields, $set, $match (with $expr), or $group.

💡 $month vs $year vs $dateTrunc

2024-06-15Z$year: 2024, $month: 6, $dayOfMonth: 15
$month — BSON Date → integer 1–12 (month of year)
$dateTrunc — BSON Date → Date at month boundary (great for monthly buckets)
JavaScriptgetMonth() is 0-based; MongoDB $month is 1-based

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (date extraction)
ArgumentsOne date expression
Return typeInteger (1–12)
Indexing1-based (January = 1)
Timezone supportYes (object form with timezone)
MongoDB version3.4+
From field
{ $month: "$orderedAt" }

Month component

June 2024
{ $month: ISODate("2024-06-15T00:00:00Z") }

Returns 6

In $project
{
  month: { $month: "$eventAt" }
}

Add computed field

With timezone
{
  $month: {
    date: "$eventAt",
    timezone: "America/New_York"
  }
}

Local month

Examples Gallery

Extract month values, filter seasonal date ranges, group sales by month, and read months in a local timezone.

📚 E-Commerce Orders

Use an orders collection and extract months from orderedAt.

Sample Input Documents

Suppose you have an orders collection with order timestamps:

mongosh
[
  {
    "_id": ObjectId("609c26812e9274a86871bc6a"),
    "product": "Winter Jacket",
    "amount": 120,
    "orderedAt": ISODate("2024-01-15T10:00:00Z")
  },
  {
    "_id": ObjectId("609c26812e9274a86871bc6b"),
    "product": "Beach Towel",
    "amount": 25,
    "orderedAt": ISODate("2024-07-20T14:30:00Z")
  },
  {
    "_id": ObjectId("609c26812e9274a86871bc6c"),
    "product": "Gift Card",
    "amount": 50,
    "orderedAt": ISODate("2024-12-01T09:00:00Z")
  }
]

Example 1 — Add month with $month

Extract the month component from each order date:

mongosh
db.orders.aggregate([
  {
    $project: {
      product: 1,
      amount: 1,
      orderedAt: 1,
      month: { $month: "$orderedAt" }
    }
  }
])

How It Works

  • January order → month 1.
  • July order → month 7.
  • December order → month 12.

📈 Practical Patterns

Seasonal filters, monthly grouping, and timezone-aware extraction.

Example 2 — Filter Summer Orders (June, July, August)

Find orders placed in months 6, 7, or 8 using $expr:

mongosh
db.orders.find({
  $expr: {
    $in: [
      { $month: "$orderedAt" },
      [ 6, 7, 8 ]
    ]
  }
})

How It Works

Combine $month with $in inside $expr. Only the July order matches. Use the same pattern for quarters: Q1 = months 1–3, Q2 = 4–6, and so on.

Example 3 — Group Revenue by Month of Year

Summarize total sales for each month across all years:

mongosh
db.orders.aggregate([
  {
    $group: {
      _id: { $month: "$orderedAt" },
      totalRevenue: { $sum: "$amount" },
      orderCount: { $sum: 1 }
    }
  },
  { $sort: { "_id": 1 } }
])

How It Works

Grouping by $month aggregates all years together — useful for “which month is busiest every year?” charts. Add $year to the _id if you need per-year monthly breakdowns.

Example 4 — Month in a Specific Timezone

Extract the month in Pacific Time rather than UTC:

mongosh
db.orders.aggregate([
  {
    $project: {
      product: 1,
      orderedAt: 1,
      monthUtc: { $month: "$orderedAt" },
      monthPacific: {
        $month: {
          date: "$orderedAt",
          timezone: "America/Los_Angeles"
        }
      }
    }
  }
])

// orderedAt: 2024-01-01T06:00:00Z
// monthUtc: 1, monthPacific: 12 (still Dec 31 locally)

How It Works

The object form with timezone converts the instant to the specified zone before extracting the month. Near month boundaries, UTC and local months can differ — always use timezone when business rules follow local calendars.

Bonus — Group by Year and Month Together

Build a year-month breakdown for detailed reporting:

mongosh
db.orders.aggregate([
  {
    $group: {
      _id: {
        year: { $year: "$orderedAt" },
        month: { $month: "$orderedAt" }
      },
      totalRevenue: { $sum: "$amount" }
    }
  },
  { $sort: { "_id.year": 1, "_id.month": 1 } }
])

How It Works

Pairing $year and $month gives you unique year-month buckets like { year: 2024, month: 7 }. This is the foundation for monthly revenue tables and trend charts.

🚀 Use Cases

  • Seasonal analysis — compare summer vs winter sales using month ranges.
  • Monthly dashboards — group revenue or events by month of year.
  • Quarter filters — select Q1–Q4 using month ranges (1–3, 4–6, etc.).
  • Subscription billing — identify renewal months or anniversary dates.

🧠 How $month Works

1

MongoDB resolves the date

The input expression is evaluated per document — a field, $$NOW, or literal ISODate.

Input
2

$month extracts the month

MongoDB reads the month as an integer 1–12 (UTC or specified timezone).

Extract
3

An integer is returned

The number is ready for $match, $group, or seasonal filters.

Output
=

Month for seasonal analytics

Combine with $year, $dayOfMonth, and $dateTrunc for richer date reporting.

Conclusion

The $month operator extracts the month component from BSON dates in MongoDB aggregation pipelines. It is especially useful for seasonal reports, monthly dashboards, and quarter-based filters.

Remember it returns 1–12 (not 0–11 like JavaScript), uses UTC by default, and supports an optional timezone. Next in the series: $multiply.

💡 Best Practices

✅ Do

  • Remember $month is 1-based (January = 1)
  • Combine with $year for year-month reporting
  • Pass timezone when seasonal rules follow local calendars
  • Use $dateTrunc when you need full monthly Date buckets
  • Store dates as BSON Date type for reliable extraction

❌ Don’t

  • Assume 0-based months like JavaScript getMonth()
  • Use it on string dates without converting to Date first
  • Forget UTC default when comparing to local fiscal periods
  • Confuse $month with $dateToString formatted output
  • Group only by month when you need per-year monthly trends (add $year)

Key Takeaways

Knowledge Unlocked

Five things to remember about $month

Use these points when working with monthly date extraction in MongoDB.

5
Core concepts
📝 02

One Date Arg

Field or ISODate.

Syntax
🛠 03

UTC Default

Timezone optional.

Timezone
🔄 04

Not JS getMonth

1-based, not 0.

Edge case
📑 05

Date Family

$year, $dayOfMonth.

Related

❓ Frequently Asked Questions

$month returns an integer from 1 to 12 representing the month of a BSON Date. January is 1, June is 6, and December is 12.
Simple form: { $month: <dateExpression> }. With timezone: { $month: { date: <dateExpression>, timezone: <tz> } }. Pass a field like "$orderedAt" or a literal ISODate.
By default, $month uses UTC. To get the month in a specific timezone, use the object form with a timezone string like "America/New_York".
$month is 1-based: January = 1, December = 12. This differs from JavaScript's Date.getMonth(), which is 0-based (January = 0).
$month returns an integer 1–12 for the month component. $dateTrunc returns a Date rounded down to a period boundary (month, day, year) — better for monthly buckets as full dates.

Continue the Operator Series

Move on to $multiply for arithmetic, or review $year for year extraction.

Next: $multiply →

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