MongoDB $dateToParts Operator

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

What Is $dateToParts?

$dateToParts is a MongoDB aggregation expression that splits a BSON Date into numeric pieces—year, month, day, hour, minute, second, and millisecond—and returns them as one document.

Remember
$dateToParts = Date → { year, month, day, ... }

{ $dateToParts: {
    date:     <dateExpression>,   // required
    timezone: <string>,           // optional (default UTC)
    iso8601:  <boolean>           // optional (default false)
  }
}

default parts → year, month, day, hour, minute, second, millisecond
iso8601:true  → isoWeekYear, isoWeek, isoDayOfWeek + time fields

null / missing date → null
UsePrefer
Split a Date into components$dateToParts
Build a Date from components$dateFromParts
Format a Date as text$dateToString

How to Use $dateToParts in MongoDB

Point at a Date field, then read the parts you need from the returned document.

  1. Choose an expression stage ($addFields or $project).
  2. Set date to a Date field (or Date expression).
  3. Optionally set timezone for local calendar parts, or iso8601: true for ISO week fields.
  4. Use dotted paths (for example "$parts.year") when you need one component.
PieceRequired?Role
dateYesDate / Timestamp / ObjectId to split
timezoneNoLocal parts instead of UTC
iso8601Notrue → ISO week-date fields

Pseudocode

Pseudocode
for each document:
    d = evaluate(date)
    if d is null or missing:
        result = null
    else:
        result = {
          year, month, day,
          hour, minute, second, millisecond
        }   // or ISO week fields if iso8601 is true
    emit { ..., field: result }

Cheat Sheet

Keep these facts handy while splitting dates into parts.

TopicDetail
TypeAggregation expression (not a find filter)
Syntax{ $dateToParts: { date: "$starts_at" } }
ReturnsA document of integer parts
Default fieldsyear, month, day, hour, minute, second, millisecond
ISO week modeiso8601: true → isoWeekYear, isoWeek, isoDayOfWeek
Inverse$dateFromParts
Sample check2026-10-02 → year 2026, month 10, day 2

Live Preview

Watch $dateToParts turn a Date into year, month, day, and time fields (UTC).

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

Result
date = ISODate("2026-10-02T09:15:00.000Z")

$dateToParts → {
  year: 2026,
  month: 10,
  day: 2,
  hour: 9,
  minute: 15,
  second: 0,
  millisecond: 0
}

Worked Walkthrough — Split a Start Time

An event starts at 2026-10-02T09:15:00Z. We want separate numbers for year, month, day, and time.

Calculation
Document:
  { starts_at: ISODate("2026-10-02T09:15:00.000Z") }

$dateToParts: { date: "$starts_at" }

Step by step (UTC):
  year        → 2026
  month       → 10
  day         → 2
  hour        → 9
  minute      → 15
  second      → 0
  millisecond → 0

Result document:
  { year: 2026, month: 10, day: 2, hour: 9, minute: 15, second: 0, millisecond: 0 }

MongoDB Examples

We use one event with a start time. First we store it, then we split it into parts, then we project just year and month. 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 (one Date value)
Picture
One Date value:

  starts_at = 2026-10-02T09:15:00.000Z

After $dateToParts:

  year: 2026
  month: 10
  day: 2
  hour: 9
  minute: 15
  ...

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 $dateToParts next.

Example 2 — Split into Parts

Goal: turn starts_at into a document of calendar and time parts.

mongosh
db.events.aggregate([
  {
    $addFields: {
      parts: {
        $dateToParts: {
          date: "$starts_at"
        }
      }
    }
  }
]);

How It Works

  1. Read the stored Date. MongoDB already has starts_at from Example 1.
  2. Split in UTC. With no timezone, parts match the UTC clock.
  3. Get a nested document. parts holds integers you can group or filter on.
  4. Keep all fields. $addFields adds parts next to starts_at—nothing is deleted.

Example 3 — Year and Month Only

Same date, but keep only the pieces you need for a monthly report.

mongosh
db.events.aggregate([
  {
    $addFields: {
      parts: {
        $dateToParts: { date: "$starts_at" }
      }
    }
  },
  {
    $project: {
      title: 1,
      year: "$parts.year",
      month: "$parts.month"
    }
  }
]);

How It Works

  1. Same split first. $dateToParts still builds the full parts document.
  2. Pick fields with dotted paths. "$parts.year" and "$parts.month" pull two integers out.
  3. Shape the report. $project keeps only title, year, and month.
  4. Easy check. October 2026 matches the original start date.

Edge Cases & Pitfalls

Check these before using $dateToParts in production pipelines.

type

Input must be a Date

String dates need $dateFromString first. $dateToParts does not parse text.

tz

Default parts are UTC

A late evening in New York can still be the next UTC day. Set timezone when reports must match local calendars.

iso

ISO week fields replace year/month/day

With iso8601: true, look for isoWeekYear / isoWeek / isoDayOfWeek—not year / month / day.

null

Null date becomes null

Missing or null dates return null, not an empty parts document. Handle them before grouping if needed.

Performance Notes

ApproachCostBest for
$dateToParts alonePer-document splitReports that need several calendar fields
+ $project selected fieldsStill O(docs)Keeping only year/month for grouping
Single-field helpers ($year, …)Often lighterWhen you need only one component

Splitting dates is cheap compared with large sorts or joins. Filter early with $match when only some documents need parts.

Key Takeaways

  • Role: Date → document of integer parts.
  • Default: year, month, day, plus time fields (UTC).
  • Inverse: rebuild with $dateFromParts.
  • Access: use paths like "$parts.year" after the split.

One line: $dateToParts answers “what are the year, month, day, and time pieces of this Date?”

Frequently Asked Questions

$dateToParts breaks a BSON Date into numeric components such as year, month, day, hour, minute, second, and millisecond. It returns a document of integers, not a single number.
Use { $dateToParts: { date: <dateExpression>, timezone: <string>, iso8601: <boolean> } }. Only date is required. timezone and iso8601 are optional.
$dateToParts splits one Date into components. $dateFromParts builds one Date from components. They are inverse operations.
Instead of year/month/day, you get isoWeekYear, isoWeek, and isoDayOfWeek (plus the usual time fields). Use it for ISO week-date reporting.
By default parts are in UTC. Pass an Olson ID such as "America/New_York" to extract parts as they appear in that local zone.
Run $dateToParts, then read the year field with $getField, or project "parts.year". For a single field, $year is a shorter alternative.

Next: $dateToString

Format a BSON Date into a readable string with a format pattern.

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