$dateTrunc is a MongoDB aggregation expression that rounds a Date down to the start of a time period—day, month, hour, and more. Use it to bucket events for daily or monthly reports (MongoDB 5.0+).
Remember
$dateTrunc = snap Date to period start
{ $dateTrunc: {
date: <date>, // required
unit: <string>, // required e.g. "day"
binSize: <number>, // optional default 1
timezone: <string>, // optional default UTC
startOfWeek: <string> // optional for unit "week"
}
}
units → year, quarter, week, month, day,
hour, minute, second
returns → a new Date at the boundary
example → 09:15 truncated to day → 00:00 same day
Optionally set binSize, timezone, or startOfWeek (for weeks).
Piece
Required?
Role
date
Yes
Date / Timestamp / ObjectId to truncate
unit
Yes
Period boundary ("day", "month", …)
binSize
No
Bucket width in units (default 1)
timezone / startOfWeek
No
Local calendar / week start day
Pseudocode
Pseudocode
for each document:
d = evaluate(date)
u = evaluate(unit)
if d is null or missing:
result = null
else:
result = start of the period containing d
// e.g. unit "day" → midnight of that day
emit { ..., field: result }
Reference
Cheat Sheet
Keep these facts handy while truncating dates for buckets.
unit: "day" → midnight of that day (UTC by default)
Month bucket
unit: "month" → first day of that month
binSize
unit: "hour", binSize: 2 → every 2 hours
Sample check
2026-10-02 09:15 → day trunc → 2026-10-02 00:00
Try it
Live Preview
Watch $dateTrunc snap a timestamp down to day, hour, or month (UTC).
Simulates $dateTrunc for ISODate("2026-10-02T09:15:00.000Z").
Result
date = ISODate("2026-10-02T09:15:00.000Z")
unit = "day"
$dateTrunc → ISODate("2026-10-02T00:00:00.000Z")
{ day_bucket: ISODate("2026-10-02T00:00:00.000Z") }
Trace
Worked Walkthrough — Truncate to Day
An event starts at 2026-10-02T09:15:00Z. For a daily report we want midnight of that same day.
Calculation
Document:
{ starts_at: ISODate("2026-10-02T09:15:00.000Z") }
$dateTrunc: {
date: "$starts_at",
unit: "day"
}
Step by step (UTC):
1) Read 2026-10-02 09:15
2) Keep the calendar day
3) Clear time → 00:00:00.000
Result:
ISODate("2026-10-02T00:00:00.000Z")
All events that day share this bucket key.
Code
MongoDB Examples
We use one event with a start time. First we store it, then we truncate to day, then to 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.
Exact time:
2026-10-02 09:15:00 UTC
|
v $dateTrunc unit:"day"
2026-10-02 00:00:00 UTC ← day bucket
|
v $dateTrunc unit:"month"
2026-10-01 00:00:00 UTC ← month bucket
How It Works
Insert once.insertOne adds a single event document to events.
Store a real Date.ISODate(...) creates a BSON Date, not a string.
find() shows the same shape. What you inserted is what you get back—ready for $dateTrunc next.
Example 2 — Truncate to Day
Goal: snap starts_at to midnight of the same UTC day for daily grouping.
Same stored document. Still using starts_at from Example 1.
Change the unit."month" instead of "day".
Land on month start. October 2 becomes October 1 at 00:00:00.000Z.
Easy check. All October events share the same month bucket key.
Edge Cases & Pitfalls
Check these before using $dateTrunc in production pipelines.
type
Input must be a Date
String dates need $dateFromString first. $dateTrunc does not parse text.
tz
Default buckets are UTC
A late evening in New York can fall on the next UTC day. Set timezone when daily buckets must match a local calendar.
week
Week start defaults to Sunday
For Monday-based weeks, set startOfWeek: "Monday" when unit is "week".
null
Null date becomes null
Missing or null dates return null, not an error. Filter them before grouping if null buckets are unwanted.
Analysis
Performance Notes
Approach
Cost
Best for
$dateTrunc alone
Per-document date math
Daily / monthly group keys
+ $group on the bucket
O(docs) + grouping
Rollups and time-series summaries
+ timezone
Slightly heavier
Local-day reporting near DST
Truncation is cheap compared with large sorts or joins. Filter early with $match when only some documents need a bucket.
Remember
Key Takeaways
Role: snap a Date down to a period start.
Inputs:date + unit (optional binSize).
Returns: a Date (great as a $group key).
Pattern:unit: "day" for daily buckets.
One line:$dateTrunc answers “what is the start of this day/month/hour for my Date?”
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 daily rollups, time-series bucketing, and grouping events by calendar periods (MongoDB 5.0+).
Use { $dateTrunc: { date: <date>, unit: <string>, binSize: <number>, timezone: <string>, startOfWeek: <string> } }. date and unit are required. binSize defaults to 1.
year, quarter, week, month, day, hour, minute, and second. Pass the unit as a string such as "day" or "month".
$dateTrunc returns a BSON Date at a period boundary. $dateToParts returns a document of numeric components. Use $dateTrunc when you need a Date for grouping; use $dateToParts when you need separate integers.
binSize sets how many units make one bucket. For example, unit "hour" and binSize 2 truncates to every 2-hour boundary. It defaults to 1.
No. It computes a new Date in the pipeline result. Your original field stays unchanged unless you write the result back with an update.