MongoDB $month Operator

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

What Is $month?

$month is a MongoDB aggregation expression that returns the month of a date as an integer from 1 to 12. January is 1, December is 12—unlike JavaScript’s getMonth(), which is 0-based.

Remember
$month = month number (1 … 12)

{ $month: <dateExpression> }

{ $month: { date: <date>, timezone: <tz> } }

ISODate("2014-01-01…") → 1  (January)
ISODate("2014-06-15…") → 6  (June)
ISODate("2014-12-25…") → 12 (December)

null / missing → null
string date → pipeline error
UsePrefer
Month number (1–12)$month
Year number$year
Day of month (1–31)$dayOfMonth

How to Use $month in MongoDB

Pass a BSON date field (or expression), optionally with a timezone.

  1. Choose an expression stage ($addFields or $project).
  2. Pass a Date / Timestamp / ObjectId expression to $month.
  3. Use the short form for UTC, or the document form with timezone for local month.
  4. Combine with $year or $dayOfMonth when you need a full calendar breakdown.
PieceRequired?Role
$monthYesReturns month 1–12
Date expressionYesDate, Timestamp, or ObjectId
timezoneNoOlson id or UTC offset (default: UTC)

Pseudocode

Pseudocode
for each document:
    d = evaluate(dateExpression)
    if d is null or missing:
        result = null
    else if d is a string:
        error  // aggregation fails
    else:
        result = month part of d   // 1 … 12 (UTC or timezone)
    emit { ..., field: result }

Cheat Sheet

Keep these facts handy while extracting months.

TopicDetail
TypeAggregation expression (not a find filter)
Syntax{ $month: <date> }
Range1 … 12 (Jan … Dec)
vs JavaScriptMongoDB is 1-based; getMonth() is 0-based
Input typesDate, Timestamp, ObjectId
Default zoneUTC
StringsNot allowed — convert first

Live Preview

Watch $month return 1–12 from a timestamp (UTC).

Simulates $month in UTC (same idea as the mongosh examples below).

Result
date = 2014-01-01T08:15:39.736Z
$month → 1 (January)

{ month: 1 }

Worked Walkthrough — Sale Date

A sale was recorded at 2014-01-01T08:15:39.736Z. We want the month number.

Calculation
Document:
  { item: "abc", date: ISODate("2014-01-01T08:15:39.736Z") }

Calendar parts (UTC):
  year  → 2014
  month → 1   (January)
  day   → 1

$month("$date") → 1

Check: January = 1 in MongoDB (not 0) ✓

MongoDB Examples

We use a small sales collection. First we extract the month in UTC, then show how timezone can change it. Run these in mongosh after inserting the sample data once.

Example 1 — Sample Data

Imagine two sales on different calendar months. We save them in a collection named sales.

mongosh
db.sales.insertMany([
  {
    _id: 1,
    item: "abc",
    price: 10,
    quantity: 2,
    date: ISODate("2014-01-01T08:15:39.736Z")
  },
  {
    _id: 2,
    item: "xyz",
    price: 20,
    quantity: 1,
    date: ISODate("2014-06-15T12:00:00.000Z")
  }
]);

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps two documents in sales. Run find() to see them:

mongosh
db.sales.find()

Read one document like this:

Field in MongoDBValue (doc 1)Plain English
_id1Document id
item"abc"Product code
date2014-01-01…Sale time (BSON Date)

How It Works

  1. Insert once. insertMany adds two sale documents to sales.
  2. Dates are BSON Date. Use ISODate(...), not plain strings.
  3. find() shows the same shape. Ready for $month next.

Example 2 — Extract Month

Goal: read the 1–12 month portion of each sale’s date (UTC).

mongosh
db.sales.aggregate([
  {
    $addFields: {
      month: { $month: "$date" }
    }
  }
]);

How It Works

  1. Read the stored date. Document 1 is in January 2014 (UTC).
  2. Extract month. $month: "$date" returns 1.
  3. Second document. June 15 → month 6.
  4. Keep all fields. $addFields adds month next to the original sale data.

Example 3 — Month with Timezone

Near midnight UTC, a negative offset can push the local calendar into the previous month. Here we compare UTC vs -0500 on New Year’s Day.

mongosh
db.sales.aggregate([
  { $match: { _id: 1 } },
  {
    $project: {
      item: 1,
      utcMonth: { $month: "$date" },
      localMonth: {
        $month: {
          date: ISODate("2000-01-01T00:00:00Z"),
          timezone: "-0500"
        }
      }
    }
  }
]);

How It Works

  1. UTC month for the sale. Doc 1’s date is January → utcMonth: 1.
  2. Demo instant. 2000-01-01T00:00:00Z is midnight UTC on New Year’s Day.
  3. Apply -0500. Local time becomes 1999-12-31T19:00:00 → month 12.
  4. Lesson. Near day boundaries, timezone can change year and month—state the zone you mean.

Edge Cases & Pitfalls

Check these before using $month in production pipelines.

base

MongoDB is 1-based

January is 1, not 0. Do not copy JavaScript getMonth() habits into MongoDB pipelines.

type

No string dates

Passing "2014-01-01" fails. Store BSON Date, or convert with $toDate / $dateFromString first.

tz

Timezone can change the month

Around midnight UTC, an offset like -0500 can move you into the previous month (or next). Always state the zone.

null

Null and missing become null

Missing fields return null, not an error. Handle them before grouping by month if nulls are invalid.

Performance Notes

ApproachCostBest for
$month alonePer-document date mathNeed only the month number
$month + $yearStill O(docs)Monthly reports / grouping keys
+ timezoneSmall extra conversionLocal calendar months

Date-part expressions are cheap compared with large sorts or joins. Filter early with $match when only some documents need the month value. For monthly buckets as full dates, consider $dateTrunc.

Key Takeaways

  • Role: date → month 1–12.
  • 1-based: January = 1, not 0.
  • Input: Date / Timestamp / ObjectId (not strings).
  • Timezone: can change month near midnight.

One line: $month answers “which month number (1–12) is this date?”—in aggregation.

Frequently Asked Questions

$month returns an integer from 1 to 12 for the month of a date. January is 1, June is 6, and December is 12. Use it inside aggregation expression stages such as $project and $addFields.
Short form: { $month: <dateExpression> }. Document form: { $month: { date: <dateExpression>, timezone: <tz> } }. The date must resolve to a Date, Timestamp, or ObjectId—not a string.
$month is 1-based: January = 1, December = 12. That differs from JavaScript’s Date.getMonth(), which is 0-based (January = 0).
Yes by default. Pass timezone (Olson id like "America/New_York" or an offset like "-0500") in the document form when you need the local month. Near midnight UTC, timezone can change the month.
$month returns null when the input is null or the field is missing. A plain string date causes an aggregation error.
No. Strings like "2014-01-01" cause an error. Store BSON Date / ISODate, or convert first with $toDate / $dateFromString.

Next: $multiply

Multiply two or more numbers in an aggregation pipeline.

$multiply 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