MongoDB $toDate Operator

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

What Is $toDate?

$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
UsePrefer
Simple convert to Date$toDate
Convert with onError / onNull$convert
Parse custom date strings$dateFromString

How to Use $toDate in MongoDB

Convert the field to a real Date, then sort, filter, or format it.

  1. Choose an expression stage ($addFields or $project).
  2. Pass the string, number, or ObjectId expression to $toDate.
  3. Optional: sort or match on the converted date.
  4. If strings may be invalid, prefer $convert with onError.
PieceRequired?Role
$toDateYesConvert expression → Date (or null)
ExpressionYesISO string, millis, ObjectId, Timestamp, or Date
$convert / $dateFromStringNoSafer 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 }

Cheat Sheet

Keep these facts handy while converting dates in pipelines.

TopicDetail
TypeAggregation 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 exampleMilliseconds since Unix epoch
ObjectIdUses the ObjectId’s embedded timestamp
Invalid stringErrors—use $convert.onError for soft fails

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).

Result
input = "2018-03-20"
$toDate → ISODate("2018-03-20T00:00:00.000Z")

{ asDate: ISODate("2018-03-20T00:00:00.000Z") }

Worked Walkthrough — String Dates

Two orders store dates as strings. Convert them so you can sort chronologically.

Calculation
Documents:
  { item: "apple", order_date: "2018-03-20" }
  { item: "pie",   order_date: "2018-03-15" }

$toDate("2018-03-20") → ISODate("2018-03-20T00:00:00Z")
$toDate("2018-03-15") → ISODate("2018-03-15T00:00:00Z")

Sort by convertedDate ascending:
  pie (Mar 15) → apple (Mar 20)

MongoDB Examples

Insert sample orders with string dates, convert with $toDate, then sort. Run these in mongosh in order.

Example 1 — Sample Data

Two orders store order_date as an ISO-style string (common when importing CSV or JSON).

mongosh
db.orders.insertMany([
  { _id: 1, item: "apple", order_date: "2018-03-20" },
  { _id: 2, item: "pie", order_date: "2018-03-15" }
]);

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps two documents in orders. Run find() to see them:

mongosh
db.orders.find()

Read the rows like this:

FieldExamplesPlain English
_id1, 2Document id
item"apple", "pie"Product name
order_date"2018-03-20", …Date stored as a string (not a Date yet)

How It Works

  1. Insert two orders. insertMany stores simple documents for the lesson.
  2. Dates are strings. MongoDB does not auto-convert "2018-03-20" to a Date on insert.
  3. Ready to convert. The next example turns those strings into real dates.

Example 2 — Convert with $toDate

Goal: add a convertedDate field as a BSON Date for every order.

mongosh
db.orders.aggregate([
  {
    $addFields: {
      convertedDate: { $toDate: "$order_date" }
    }
  }
]);

How It Works

  1. Read each string. order_date still holds the original text from Example 1.
  2. Convert to Date. $toDate parses the ISO-style string into a BSON Date.
  3. Midnight UTC for date-only strings. "2018-03-20" becomes 2018-03-20T00:00:00.000Z.
  4. Keep originals. $addFields adds convertedDate without removing order_date.

Example 3 — Sort by Date

Convert first, then sort oldest to newest (pie before apple).

mongosh
db.orders.aggregate([
  {
    $addFields: {
      convertedDate: { $toDate: "$order_date" }
    }
  },
  {
    $sort: { convertedDate: 1 }
  }
]);

How It Works

  1. Same conversion. Stage one builds convertedDate like Example 2.
  2. Sort on the Date field. $sort: { convertedDate: 1 } orders chronologically.
  3. 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.
  4. 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.

Performance Notes

ApproachCostBest for
$toDate per queryPer-document parseOccasional conversion
Store real DatesCheapest long-termFields you sort/filter often
$convert + onErrorSlightly more workDirty 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.

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.

Next: $toDecimal

Convert values to Decimal128 in an aggregation pipeline.

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