Date Type: UTC, Time Zones, and Date Queries

MongoDB's BSON Date type represents a point in time as a signed 64-bit integer containing milliseconds since the Unix epoch. It does not store an arbitrary time-zone name as part of the Date value.

For example:

{
 createdAt: ISODate("2026-10-22T10:30:00Z")
}

The Z suffix indicates UTC.

BSON Date versus a string

These documents contain different types:

{ createdAt: ISODate("2026-10-22T10:30:00Z") }
{ createdAt: "2026-10-22T10:30:00Z" }

The first contains a BSON Date. The second contains a string. Store dates as BSON Dates when chronological comparisons and date arithmetic are required.

Creating dates in mongosh

new Date()

This creates a JavaScript Date representing the current instant. When inserted through the MongoDB shell, it is stored as a BSON Date.

A fixed date can be created using:

new Date("2026-10-22T10:30:00Z")

Filtering by a date range

db.events.find({
 createdAt: {
 $gte: ISODate("2026-10-01T00:00:00Z"),
 $lt: ISODate("2026-11-01T00:00:00Z")
 }
});

This selects events in October 2026 using an inclusive lower boundary and exclusive upper boundary.

Half-open ranges are useful because consecutive intervals can be joined without overlapping at the boundary.

Time zones

A Date represents an instant, not a local calendar label. A local time such as 9:00 a.m. in Asia/Kolkata should be converted to the corresponding UTC instant before being stored if it represents a specific moment.

For example, India Standard Time is UTC+05:30. A local time of 2026-10-22 09:00 in that time zone corresponds to 2026-10-22T03:30:00Z.

When working with user schedules, recurring events, or appointments, consider whether the application needs to retain the user's time-zone identifier in addition to the stored instant.

Date range filtering by local day

To query all records for a particular local calendar day, calculate the UTC start of that local day and the UTC start of the next local day using the intended time zone. Query with $gte and $lt using those two instants.

Do not assume that every local day is exactly 24 hours in every time zone; daylight-saving transitions can produce shorter or longer local days.

Date arithmetic

MongoDB's aggregation framework provides date operators for extracting components, formatting dates, calculating differences, and performing date arithmetic. These operations are covered in greater detail in the aggregation chapters.

Avoid storing queryable dates as strings

ISO-formatted strings may sort lexicographically in useful ways under restricted conditions, but they are not equivalent to BSON Dates and do not provide the same date-query semantics.

Insert dates and query a date range
db.dateExamples.insertMany([
 {
 event: "A",
 createdAt: ISODate("2026-10-01T00:00:00Z")
 },
 {
 event: "B",
 createdAt: ISODate("2026-10-15T12:30:00Z")
 },
 {
 event: "C",
 createdAt: ISODate("2026-11-01T00:00:00Z")
 }
]);

// October 2026 only.
db.dateExamples.find({
 createdAt: {
 $gte: ISODate("2026-10-01T00:00:00Z"),
 $lt: ISODate("2026-11-01T00:00:00Z")
 }
});
💡 The range includes the first instant of October and excludes the first instant of November. The result includes events A and B, but not C. Storing dates as BSON Date values allows MongoDB to perform chronological comparisons reliably.
Key Takeaways
  • BSON Date stores a point in time with millisecond precision.
  • A BSON Date does not retain an arbitrary time-zone identifier.
  • Use UTC instants consistently for date comparisons.
  • Half-open date ranges avoid overlapping consecutive periods.
  • Convert local-day boundaries using the intended time zone.
Knowledge Check

What does a BSON Date primarily represent?