$toDate is a MongoDB aggregation expression that converts a value to a BSON Date (shown as ISODate in mongosh). It is shorthand for { $convert: { input: <expr>, to: "date" } }.
Remember
$toDate = convert value → BSON Date
{ $toDate: <expression> }
ISO string → date
millis (num) → date since/before 1970-01-01
ObjectId → ObjectId creation time
null/missing → null
invalid → pipeline error
Pass the string, number, or ObjectId expression to $toDate.
Optional: sort or match on the converted date.
If strings may be invalid, prefer $convert with onError.
Piece
Required?
Role
$toDate
Yes
Convert expression → Date (or null)
Expression
Yes
ISO string, millis, ObjectId, Timestamp, or Date
$convert / $dateFromString
No
Safer or format-aware parsing
Pseudocode
Pseudocode
for each document:
x = evaluate(expression)
if x is null or missing:
result = null
else if x is Date:
result = x
else if x is convertible string / millis / ObjectId / Timestamp:
result = date(x)
else:
error // aggregation fails
emit { ..., field: result }
Reference
Cheat Sheet
Keep these facts handy while converting dates in pipelines.
Topic
Detail
Type
Aggregation expression (not a find filter)
Syntax
{ $toDate: <expression> }
Shorthand for
{ $convert: { input: <e>, to: "date" } }
String example
"2018-03-20" → ISODate("2018-03-20T00:00:00Z")
Number example
Milliseconds since Unix epoch
ObjectId
Uses the ObjectId’s embedded timestamp
Invalid string
Errors—use $convert.onError for soft fails
Try it
Live Preview
Pick an input and see the Date MongoDB-style conversion would produce (browser demo of the same idea).
Simulates $toDate for ISO strings and epoch millis (same idea as the mongosh examples below).
Same conversion. Stage one builds convertedDate like Example 2.
Sort on the Date field.$sort: { convertedDate: 1 } orders chronologically.
Why convert first? Sorting the raw strings can work for ISO YYYY-MM-DD, but a real Date is safer for mixed formats, times, and comparisons.
Oldest first. March 15 (pie) appears before March 20 (apple).
Edge Cases & Pitfalls
Check these before using $toDate in production pipelines.
invalid
Bad strings fail the pipeline
Values like "Friday" throw a conversion error. Use $convert with onError for messy data.
null
Null and missing become null
$toDate returns null for null/missing inputs—it does not invent a date.
millis
Numbers mean milliseconds
Numeric inputs are Unix epoch milliseconds, not seconds. Passing seconds will land far in 1970.
format
Need a custom format? Use $dateFromString
For non-ISO layouts or timezone options, prefer $dateFromString.
Analysis
Performance Notes
Approach
Cost
Best for
$toDate per query
Per-document parse
Occasional conversion
Store real Dates
Cheapest long-term
Fields you sort/filter often
$convert + onError
Slightly more work
Dirty imported strings
Prefer storing BSON Dates when you control the write path. Converting on every read is fine for cleaning, but index and sort on real Date fields when you can.
Remember
Key Takeaways
Role: convert a value to a BSON Date.
Inputs: ISO strings, millis, ObjectId, Timestamp, Date.
Invalid: bad strings error—use $convert for soft fails.
Shorthand: same as $convert to "date".
One line:$toDate answers “turn this value into a real Date so I can sort and compare it.”
Frequently Asked Questions
$toDate converts a value to a BSON Date (ISODate) inside an aggregation pipeline. Use it in stages such as $project and $addFields.
ISO date strings, numeric millisecond timestamps, ObjectIds (uses the embedded creation time), Timestamp values, and existing Date values. null or missing returns null.
$toDate is shorthand for { $convert: { input: <expr>, to: "date" } }. Use $convert with onError when invalid values should return a fallback instead of failing the pipeline.
$toDate throws a conversion error (for example, "Friday"). Use $convert with onError when working with messy imported data.
Use $dateFromString when you need a custom format, timezone, or onError/onNull options for string parsing. Use $toDate for simple ISO-style strings and other convertible types.
No. Aggregation expressions compute values in the pipeline result. Use an update pipeline if you want to persist the converted date.