MongoDB $dateToString Operator

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

What Is $dateToString?

$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)
UsePrefer
Format a Date as text$dateToString
Parse text into a Date$dateFromString
Split a Date into numbers$dateToParts

How to Use $dateToString in MongoDB

Point at a Date field, choose a format pattern, then optionally set timezone or a null fallback.

  1. Choose an expression stage ($addFields or $project).
  2. Set date to a Date field (or Date expression).
  3. Set format (for example "%Y-%m-%d" or "%d/%m/%Y %H:%M").
  4. Optionally set timezone for local clock text, or onNull for missing dates.
PieceRequired?Role
dateYesDate / Timestamp / ObjectId to format
formatNoPattern with %Y, %m, %d, …
timezone / onNullNoLocal 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 }

Cheat Sheet

Keep these facts handy while formatting dates as strings.

TopicDetail
TypeAggregation expression (not a find filter)
Common syntax{ $dateToString: { date: "$starts_at", format: "%Y-%m-%d" } }
Date only"%Y-%m-%d" → "2026-10-02"
Date + time"%Y-%m-%d %H:%M" → "2026-10-02 09:15"
Day/month style"%d/%m/%Y" → "02/10/2026"
Inverse$dateFromString
Sample check2026-10-02 09:15 UTC → "2026-10-02" with "%Y-%m-%d"

Live Preview

Watch $dateToString turn a Date into text with different format patterns (UTC).

Simulates $dateToString for ISODate("2026-10-02T09:15:00.000Z").

Result
date = ISODate("2026-10-02T09:15:00.000Z")
format = "%Y-%m-%d"

$dateToString → "2026-10-02"

{ label: "2026-10-02" }

Worked Walkthrough — Date Label

An event starts at 2026-10-02T09:15:00Z. We want a simple display string: "2026-10-02".

Calculation
Document:
  { starts_at: ISODate("2026-10-02T09:15:00.000Z") }

$dateToString: {
  date: "$starts_at",
  format: "%Y-%m-%d"
}

Step by step (UTC):
  %Y → 2026
  %m → 10
  %d → 02
  join with "-" → "2026-10-02"

Result:
  "2026-10-02"

MongoDB Examples

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.

mongosh
db.events.insertOne({
  _id: 1,
  title: "Launch",
  starts_at: ISODate("2026-10-02T09:15:00.000Z")
});

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps one document in events. Run find() to see it:

mongosh
db.events.find()

Read that document like this:

Field in MongoDBValuePlain English
_id1Document id (row number for this lesson)
title"Launch"Event name
starts_atISODate("2026-10-02T09:15:00.000Z")Start time (real Date, not a string yet)
Picture
Date in → text out:

  starts_at = 2026-10-02T09:15:00.000Z

  format "%Y-%m-%d"      → "2026-10-02"
  format "%Y-%m-%d %H:%M" → "2026-10-02 09:15"

How It Works

  1. Insert once. insertOne adds a single event document to events.
  2. Store a real Date. ISODate(...) creates a BSON Date, not a string.
  3. find() shows the same shape. What you inserted is what you get back—ready for $dateToString next.

Example 2 — Date-Only Label

Goal: format starts_at as "YYYY-MM-DD" for a simple label.

mongosh
db.events.aggregate([
  {
    $addFields: {
      label: {
        $dateToString: {
          date: "$starts_at",
          format: "%Y-%m-%d"
        }
      }
    }
  }
]);

How It Works

  1. Read the stored Date. MongoDB already has starts_at from Example 1.
  2. Apply the pattern. %Y, %m, and %d become year, month, and day.
  3. Get a string. The new field label is text: "2026-10-02".
  4. Keep all fields. $addFields adds label next to starts_at—nothing is deleted.

Example 3 — Date and Time

Same Date, but include hours and minutes in the formatted string.

mongosh
db.events.aggregate([
  {
    $addFields: {
      when_label: {
        $dateToString: {
          date: "$starts_at",
          format: "%Y-%m-%d %H:%M"
        }
      }
    }
  }
]);

How It Works

  1. Same stored document. Still using starts_at from Example 1.
  2. Extend the pattern. Add %H and %M for hour and minute (24-hour clock).
  3. Keep the space literal. Characters that are not % codes (like the space) appear as-is.
  4. 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.

Performance Notes

ApproachCostBest for
$dateToString alonePer-document formatLabels, exports, display fields
+ timezoneSlightly heavierLocal-time report text
Keep Date for queriesBest query performanceFilter/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.

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.

Next: $dateTrunc

Truncate a date to the start of a day, month, or other unit.

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