MongoDB $toDate Operator

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 5 Examples
Type Conversion

What You’ll Learn

The $toDate operator converts values to a BSON Date (ISODate) in MongoDB aggregation pipelines. Use it to parse ISO date strings, Unix millisecond timestamps, and ObjectIds into proper date types for sorting and filtering.

01

Date Conversion

Values to ISODate.

02

Syntax

One expression.

03

Input Types

String, number, ObjectId.

04

$project Stage

Parse date fields.

05

Use Cases

Imports, sorting, ranges.

06

vs $convert

Shorthand vs safe ETL.

Definition and Usage

In MongoDB’s aggregation framework, the $toDate operator converts an expression to a BSON Date value. Imported CSV and JSON data often stores dates as strings like "2024-06-15T10:30:00Z" or as Unix millisecond numbers. $toDate turns those into real dates so you can sort chronologically, filter by range, and group by month or year.

$toDate is shorthand for { $convert: { input: <expression>, to: "date" } }. It is part of the same type-conversion family as $toBool, $toInt, and $toString.

💡
Beginner Tip

ISO-8601 strings are the most common input: "2024-06-15T10:30:00Z". For messy data with invalid dates, use $convert with onError instead of bare $toDate.

📝 Syntax

The $toDate operator takes one expression:

mongosh
{ $toDate: <expression> }

Literal Examples

mongosh
{ $toDate: "2024-06-15T10:30:00Z" }
// Result: ISODate("2024-06-15T10:30:00.000Z")

{ $toDate: 1718448600000 }
// Result: ISODate from Unix milliseconds

{ $toDate: "$dateString" }
// Convert the dateString field

{ $toDate: "$_id" }
// ObjectId → creation timestamp as Date

Conversion Rules

  • null — returns null.
  • Date — returns the same date value.
  • String — parses ISO-8601 date strings (invalid strings cause an error).
  • Number — treats the value as milliseconds since the Unix epoch.
  • ObjectId — extracts the embedded creation timestamp.
  • Timestamp — converts to a Date value.
  • Use inside $project, $addFields, or $set.

💡 $toDate vs $convert

$toDate — shorthand: { $toDate: "$dateString" }
$convert — full form with onError and onNull for safe ETL
Use $toDate when data is clean; use $convert when invalid dates should not break the pipeline
See the $convert operator tutorial for flexible type conversion

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (type conversion)
Syntax{ $toDate: <expression> }
Equivalent{ $convert: { input: <expr>, to: "date" } }
String formatISO-8601 (e.g. 2024-06-15T10:30:00Z)
Number formatMilliseconds since Unix epoch
Common stages$project, $addFields, $set
ISO string
{
  $toDate: "$dateString"
}

Parse text dates

Unix ms
{
  $toDate: "$timestamp"
}

Epoch milliseconds

ObjectId
{
  $toDate: "$_id"
}

Creation time

Literal
{
  $toDate: "2024-01-01"
}

Fixed date

Examples Gallery

Parse ISO date strings, convert Unix timestamps, extract ObjectId creation times, and sort events chronologically.

📚 Event Dates

Start with an events collection where dates are stored as strings and convert them with $toDate.

Sample Input Documents

Suppose you have an events collection with date strings from a CSV import:

mongosh
[
  {
    "_id": 1,
    "title": "Product Launch",
    "dateString": "2024-06-15T10:30:00Z"
  },
  {
    "_id": 2,
    "title": "Team Meeting",
    "dateString": "2024-03-20T14:00:00Z"
  },
  {
    "_id": 3,
    "title": "Year-End Review",
    "dateString": "2024-12-01T09:00:00Z"
  }
]

Example 1 — Convert ISO String to Date

Parse the dateString field into a proper BSON date:

mongosh
db.events.aggregate([
  {
    $project: {
      title: 1,
      dateString: 1,
      eventDate: { $toDate: "$dateString" }
    }
  }
])

How It Works

$toDate parses ISO-8601 strings into BSON Date objects. Once converted, the field supports date comparisons, sorting, and date arithmetic operators like $dateDiff.

📈 Timestamps and Sorting

Convert Unix milliseconds, extract ObjectId dates, and sort chronologically.

Example 2 — Convert Unix Milliseconds

Some APIs store timestamps as numbers (milliseconds since epoch):

mongosh
db.logs.aggregate([
  {
    $project: {
      message: 1,
      loggedAt: { $toDate: "$timestampMs" }
    }
  }
])

// timestampMs: 1718448600000
// → loggedAt: ISODate("2024-06-15T10:30:00.000Z")

How It Works

When the input is a number, MongoDB treats it as milliseconds since January 1, 1970 (Unix epoch). This is common for JavaScript Date.now() values.

Example 3 — Extract Date from ObjectId

Every ObjectId embeds a creation timestamp. Convert _id to get when the document was created:

mongosh
db.orders.aggregate([
  {
    $project: {
      orderId: "$_id",
      createdAt: { $toDate: "$_id" }
    }
  }
])

// ObjectId("665a1b2c3d4e5f6789012345")
// → createdAt: ISODate from embedded timestamp

How It Works

ObjectIds contain a 4-byte timestamp as their first component. $toDate extracts that timestamp without needing a separate createdAt field.

Example 4 — Sort Events Chronologically

Convert dates first, then sort — string dates sort alphabetically, but Date values sort chronologically:

mongosh
db.events.aggregate([
  {
    $addFields: {
      eventDate: { $toDate: "$dateString" }
    }
  },
  {
    $sort: { eventDate: 1 }
  },
  {
    $project: {
      title: 1,
      eventDate: 1
    }
  }
])

How It Works

Converting to Date before sorting ensures correct chronological order. Sorting raw strings like "2024-12-01" before "2024-03-20" would give wrong results.

Example 5 — Filter by Date Range After Conversion

Convert string dates, then match events in a specific month:

mongosh
db.events.aggregate([
  {
    $addFields: {
      eventDate: { $toDate: "$dateString" }
    }
  },
  {
    $match: {
      eventDate: {
        $gte: ISODate("2024-06-01T00:00:00Z"),
        $lt:  ISODate("2024-07-01T00:00:00Z")
      }
    }
  },
  {
    $project: { title: 1, eventDate: 1 }
  }
])

// Returns only June 2024 events

How It Works

Date range queries require BSON Date values. Convert imported strings first, then use $gte and $lt for accurate range filtering.

Bonus — Safe Conversion with $convert

When date strings may be invalid, use $convert with onError instead of bare $toDate:

mongosh
db.events.aggregate([
  {
    $project: {
      title: 1,
      eventDate: {
        $convert: {
          input: "$dateString",
          to: "date",
          onError: null,
          onNull: null
        }
      }
    }
  }
])

// "2024-06-15T10:30:00Z" → ISODate(...)
// "not-a-date"           → null (no pipeline error)

How It Works

$toDate errors on invalid input. $convert with onError lets the pipeline continue and marks bad rows as null.

🚀 Use Cases

  • CSV/JSON import cleanup — parse date strings stored as text into proper BSON dates.
  • Chronological sorting — convert before $sort to avoid incorrect string ordering.
  • Date range queries — enable $gte/$lt filters on imported date fields.
  • ObjectId analysis — extract document creation time from _id without a separate timestamp field.
  • Reporting and grouping — prepare dates for $dateTrunc, $dateToString, or monthly rollups.

🧠 How $toDate Works

1

MongoDB reads the expression

The input resolves from a field path, literal string, number, or ObjectId.

Input
2

Type-specific parsing runs

Strings are parsed as ISO-8601; numbers as epoch milliseconds; ObjectIds as embedded timestamps.

Parse
3

A BSON Date is returned

The result is an ISODate value ready for sorting, filtering, and date arithmetic.

Output
=

Proper date field

Use in $sort, $match ranges, and date operators like $dateDiff.

Conclusion

The $toDate operator converts strings, numbers, and ObjectIds to BSON Date values in MongoDB aggregation pipelines. It is essential for cleaning imported data, sorting events chronologically, and running date range queries.

For data with potentially invalid date strings, prefer $convert with onError. Next in the series: $toDecimal.

💡 Best Practices

✅ Do

  • Use ISO-8601 format for date strings (2024-06-15T10:30:00Z)
  • Convert to Date before sorting or range filtering
  • Use $convert with onError for messy imported data
  • Extract creation time from ObjectId when no createdAt field exists
  • Test with null, valid, and edge-case date values

❌ Don’t

  • Sort date strings alphabetically without converting first
  • Assume any string format works (non-ISO strings may error)
  • Confuse seconds with milliseconds for numeric timestamps
  • Use bare $toDate on untrusted import data without error handling
  • Forget that null input returns null, not an error

Key Takeaways

Knowledge Unlocked

Five things to remember about $toDate

Use these points when converting values to dates in MongoDB.

5
Core concepts
📝 02

{ $toDate: x }

One argument.

Syntax
🔢 03

String / Number

ISO or epoch ms.

Input
🛠 04

Sort & Filter

Convert first.

Usage
05

Invalid str

Use $convert.

Safety

❓ Frequently Asked Questions

$toDate converts a value to a BSON Date (ISODate) inside an aggregation pipeline. It is an aggregation expression operator used in stages like $project and $addFields.
The syntax is { $toDate: <expression> }. The expression can be a field reference like "$createdAt", an ISO date string, a Unix millisecond number, or an ObjectId.
$toDate accepts ISO-8601 date strings, numeric millisecond timestamps, ObjectIds (uses embedded creation time), existing Date values, and timestamps. null returns null.
$toDate is shorthand for { $convert: { input: <expr>, to: "date" } }. Use $convert with onError when invalid date strings should return a fallback instead of failing the pipeline.
$toDate throws a conversion error for invalid strings. Use $convert with onError: null (or another fallback) when working with messy imported data.

Continue the Operator Series

Move on to $toDecimal for decimal conversion, or review $convert for flexible type transforms.

Next: $toDecimal →

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