MongoDB $dateTrunc Operator

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

What You’ll Learn

The $dateTrunc operator rounds a BSON Date down to the start of a time period — such as midnight for a day, the first of the month, or the top of the hour. Use it for time-series charts, daily rollups, and grouping events into calendar buckets.

01

Truncate Dates

Date → period start.

02

Syntax

date, unit.

03

Time Units

day, month, hour…

04

binSize

Wider time bins.

05

Use Cases

Charts, rollups.

06

vs $dateToParts

Boundary vs parts.

Definition and Usage

In MongoDB’s aggregation framework, the $dateTrunc operator takes a timestamp and returns the BSON Date at the beginning of the chosen unit period. For example, truncating ISODate("2024-06-15T14:30:45Z") to unit: "day" yields ISODate("2024-06-15T00:00:00Z") — the start of that calendar day in UTC.

💡
Beginner Tip

$dateTrunc returns a Date, not a string or number. It always rounds down to the period boundary. Requires MongoDB 5.0+.

📝 Syntax

The $dateTrunc operator takes an object with a required date and unit:

mongosh
{
  $dateTrunc: {
    date: <dateExpression>,
    unit: <string>,
    binSize: <numberExpression>,
    timezone: <stringExpression>,
    startOfWeek: <stringExpression>
  }
}

Syntax Rules

  • date — required; the BSON date to truncate (field, $$NOW, or literal).
  • unit — required; one of: year, quarter, month, week, day, hour, minute, second, millisecond.
  • binSize — optional; size of each bin in units (default 1). Use 2 with hour for two-hour buckets.
  • timezone — optional Olson timezone ID for calendar-aware truncation.
  • startOfWeek — optional when unit is week (sun, mon, etc.).
  • Returns a BSON Date at the start of the matching period.

💡 $dateTrunc vs $dateToParts vs $dateToString

$dateTrunc — BSON Date → BSON Date at period start (for bucketing)
$dateToParts — BSON Date → object of year, month, day integers
$dateToString — BSON Date → formatted text string

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (date)
Required fieldsdate, unit
Return typeBSON Date (period boundary)
Default binSize1
MongoDB version5.0+
Start of day
{
  $dateTrunc: {
    date: "$createdAt",
    unit: "day"
  }
}

Midnight UTC

Start of month
{
  $dateTrunc: {
    date: "$orderDate",
    unit: "month"
  }
}

First day of month

Hour buckets
{
  $dateTrunc: {
    date: "$loggedAt",
    unit: "hour"
  }
}

Top of the hour

With timezone
{
  $dateTrunc: {
    date: "$eventAt",
    unit: "day",
    timezone: "America/Chicago"
  }
}

Local calendar day

Examples Gallery

Truncate timestamps to day and month boundaries, build hourly time-series buckets, and group revenue by truncated periods with $dateTrunc.

📚 Truncate to the Start of a Day

Use a pageviews collection and normalize timestamps to daily boundaries.

Sample Input Documents

Suppose you have a pageviews collection with precise visit timestamps:

mongosh
[
  {
    "_id": ObjectId("609c26812e9274a86871bc6a"),
    "path": "/home",
    "visitedAt": ISODate("2024-06-15T09:12:00Z")
  },
  {
    "_id": ObjectId("609c26812e9274a86871bc6b"),
    "path": "/pricing",
    "visitedAt": ISODate("2024-06-15T18:45:30Z")
  },
  {
    "_id": ObjectId("609c26812e9274a86871bc6c"),
    "path": "/blog",
    "visitedAt": ISODate("2024-06-16T07:00:00Z")
  }
]

Example 1 — Daily Bucket with $dateTrunc

Truncate visitedAt to the start of each UTC day:

mongosh
db.pageviews.aggregate([
  {
    $project: {
      path: 1,
      visitedAt: 1,
      dayBucket: {
        $dateTrunc: {
          date: "$visitedAt",
          unit: "day"
        }
      }
    }
  }
])

How It Works

  • Both June 15 visits share the same dayBucket despite different times.
  • Truncation always rounds down — never up to the next period.
  • The result is still a BSON Date, ideal for $group keys.

📈 Practical Patterns

Monthly revenue rollups, wider bins, and timezone-aware daily buckets.

Example 2 — Group Sales by Month

Truncate order dates to month boundaries, then sum revenue per month:

mongosh
db.orders.aggregate([
  {
    $addFields: {
      monthBucket: {
        $dateTrunc: {
          date: "$orderDate",
          unit: "month"
        }
      }
    }
  },
  {
    $group: {
      _id: "$monthBucket",
      totalRevenue: { $sum: "$amount" },
      orderCount: { $sum: 1 }
    }
  },
  { $sort: { _id: 1 } }
])

How It Works

Using a truncated date as the $group key is cleaner than string formatting. All orders in June 2024 share one bucket starting at the first instant of that month.

Example 3 — Two-Hour Bins with binSize

Use binSize: 2 with unit: "hour" for wider time-series buckets:

mongosh
db.metrics.aggregate([
  {
    $project: {
      metric: 1,
      recordedAt: 1,
      twoHourBin: {
        $dateTrunc: {
          date: "$recordedAt",
          unit: "hour",
          binSize: 2
        }
      }
    }
  }
])

// 09:30 and 10:45 → same bin (08:00–10:00 boundary)
// 11:15 → next bin (10:00–12:00 boundary)

How It Works

binSize groups multiple units into one bin. Useful for dashboards that do not need minute-level precision but still want consistent Date keys instead of strings.

Example 4 — Truncate to Local Calendar Day

Apply a timezone so daily buckets follow local midnight, not UTC:

mongosh
db.events.aggregate([
  {
    $project: {
      title: 1,
      eventAt: 1,
      localDay: {
        $dateTrunc: {
          date: "$eventAt",
          unit: "day",
          timezone: "America/Los_Angeles"
        }
      }
    }
  }
])

How It Works

Without timezone, unit: "day" uses UTC midnights. With an Olson ID, truncation respects local calendar days — important for regional analytics and daylight saving boundaries.

🚀 Use Cases

  • Time-series charts — bucket events by hour, day, or month for graph axes.
  • Revenue rollups — aggregate sales by truncated month or quarter boundaries.
  • Log analysis — count errors per day without manual date math.
  • Retention cohorts — assign users to signup-week or signup-month buckets.

🧠 How $dateTrunc Works

1

MongoDB resolves the input date

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

Input
2

$dateTrunc finds the period boundary

MongoDB rounds down to the start of the unit (and binSize), optionally using timezone.

Truncate
3

A boundary Date is returned

The truncated timestamp is ready as a $group key or chart bucket label source.

Output
=

Clean time buckets

Pair with $group and $dateToString for labels, or $dateDiff to measure spans between buckets.

Conclusion

The $dateTrunc operator is the clearest way to bucket BSON dates by calendar periods in MongoDB aggregation pipelines. It replaces manual midnight calculations and string-based grouping with a single, readable expression that returns proper Date values.

Use timezone when buckets must follow local days, and binSize when you need wider intervals. Pair with $dateToString for display labels and ensure your MongoDB deployment is version 5.0 or later.

💡 Best Practices

✅ Do

  • Use $dateTrunc as $group keys for time-series rollups
  • Set timezone for local calendar bucketing
  • Pick the smallest unit that matches your chart granularity
  • Use binSize for coarser buckets without changing unit logic
  • Keep original timestamps alongside truncated buckets for drill-down

❌ Don’t

  • Use $dateTrunc on MongoDB versions before 5.0
  • Confuse truncation with rounding up — it always floors to the boundary
  • Assume UTC day buckets match local business days without timezone
  • Store truncated dates as strings — keep BSON Date type for sorting
  • Duplicate bucketing logic in app code when $dateTrunc suffices

Key Takeaways

Knowledge Unlocked

Five things to remember about $dateTrunc

Use these points when bucketing dates by time periods in MongoDB.

5
Core concepts
📝 02

Two Required

date, unit.

Syntax
🛠 03

Date Output

Boundary timestamp.

Output
🌐 04

binSize

Wider time bins.

Option
05

MongoDB 5.0+

Version requirement.

Important

❓ Frequently Asked Questions

$dateTrunc rounds a BSON Date down to the start of a time period — such as the beginning of the day, hour, or month. Use it for time-series bucketing, daily rollups, and grouping events by calendar periods.
{ $dateTrunc: { date: <date>, unit: <string>, binSize: <number>, timezone: <string>, startOfWeek: <string> } }. date and unit are required. binSize defaults to 1.
year, quarter, month, week, day, hour, minute, second, and millisecond. Pass the unit as a string such as "day" or "month".
$dateTrunc returns a BSON Date at the start of a period boundary. $dateToParts returns an object of numeric components like year and month. Use $dateTrunc when you need a date for grouping; use $dateToParts when you need separate integer fields.
$dateTrunc 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 $dayOfMonth to extract the day number from a date, or review $dateToString for formatted output labels.

Next: $dayOfMonth →

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