$dateToString is a MongoDB aggregation expression that formats a BSON Date as text using a format pattern such as "%Y-%m-%d". Use it for reports, exports, and display labels.
Remember
$dateToString = Date → formatted string
{ $dateToString: {
date: <dateExpression>, // required
format: <string>, // optional (common to set)
timezone: <string>, // optional (default UTC)
onNull: <expression> // optional fallback
}
}
common specs → %Y year, %m month, %d day,
%H hour, %M minute, %S second
null / missing date → null (unless onNull is set)
Set format (for example "%Y-%m-%d" or "%d/%m/%Y %H:%M").
Optionally set timezone for local clock text, or onNull for missing dates.
Piece
Required?
Role
date
Yes
Date / Timestamp / ObjectId to format
format
No
Pattern with %Y, %m, %d, …
timezone / onNull
No
Local display / missing-date fallback
Pseudocode
Pseudocode
for each document:
d = evaluate(date)
if d is null or missing:
result = onNull if set, else null
else:
result = format(d, formatPattern, timezone?)
emit { ..., field: result }
Reference
Cheat Sheet
Keep these facts handy while formatting dates as strings.
We use one event with a start time. First we store it, then we format a date-only label, then a date-and-time label. 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.
Same stored document. Still using starts_at from Example 1.
Extend the pattern. Add %H and %M for hour and minute (24-hour clock).
Keep the space literal. Characters that are not % codes (like the space) appear as-is.
Easy check.09:15 matches the original UTC time.
Edge Cases & Pitfalls
Check these before using $dateToString in production pipelines.
type
Input must be a Date
String dates need $dateFromString first. $dateToString formats Dates; it does not parse free text.
case
%M is minutes, not months
Month is %m (lowercase). Minute is %M (uppercase). Mixing them is a common bug.
tz
Default formatting is UTC
Set timezone when labels must match a local clock. Otherwise late evenings can show the next UTC day.
null
Null dates become null
Use onNull: "N/A" (or similar) when exports cannot tolerate null strings.
Analysis
Performance Notes
Approach
Cost
Best for
$dateToString alone
Per-document format
Labels, exports, display fields
+ timezone
Slightly heavier
Local-time report text
Keep Date for queries
Best query performance
Filter/sort on Date; format only for output
Formatting is cheap compared with large sorts or joins. Prefer keeping a real Date for filtering, and format late in the pipeline for display. Filter early with $match when only some rows need a label.
Remember
Key Takeaways
Role: Date → formatted string in aggregation.
Pattern:"%Y-%m-%d" for a simple date label.
Inverse: parse text back with $dateFromString.
Watch case:%m = month, %M = minute.
One line:$dateToString answers “print this Date as text using my format pattern.”
Frequently Asked Questions
$dateToString converts a BSON Date into a formatted text string inside aggregation. Use it for reports, CSV exports, labels, or any display-friendly date text.
Use { $dateToString: { date: <date>, format: <string>, timezone: <string>, onNull: <expression> } }. date is required. format, timezone, and onNull are optional—format has ISO-style defaults if omitted.
$dateToString formats a Date into a string. $dateFromString parses a string into a Date. They are inverse operations.
%Y is year, %m month, %d day, %H hour, %M minute, %S second, and %L millisecond. Example: "%Y-%m-%d" becomes 2026-10-02.
Without onNull, $dateToString returns null. Set onNull to a fallback string (for example "N/A") when you want a safe display value.
Similar idea—Date in, text out—but MongoDB uses format specifiers such as %Y and %m. Run it in the aggregation pipeline, not as a standalone find() filter.