MongoDB $hour Operator

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

What Is $hour?

$hour is a MongoDB aggregation expression that returns the hour portion of a date as an integer from 0 to 23. By default the hour is in UTC; you can pass an optional timezone.

Remember
$hour = get hour (0–23) from a date

{ $hour: <dateExpression> }

{ $hour: { date: <date>, timezone: <tz> } }

input  → Date / Timestamp / ObjectId  (not a string)
default → UTC
output → 0 … 23

2:30 PM UTC → 14
UsePrefer
Hour of day (0–23)$hour
Minute / second$minute / $second
All date parts at once$dateToParts

How to Use $hour in MongoDB

Point it at a date field, then choose UTC or a timezone for the result.

  1. Choose an expression stage ($addFields or $project).
  2. Pass a Date field (or expression) to $hour.
  3. Optional: use { date, timezone } for a local hour (Olson name or UTC offset).
  4. Use the integer in filters, groups, or labels (for example morning vs evening).
PieceRequired?Role
$hourYesExtract hour 0–23
Date expressionYesDate, Timestamp, or ObjectId
timezoneNoOlson id or offset; default UTC

Pseudocode

Pseudocode
for each document:
    d = evaluate(dateExpression)
    if timezone provided:
        local = convert(d, timezone)
        result = hour_of(local)     // 0–23
    else:
        result = hour_of(d in UTC)  // 0–23
    emit { ..., field: result }

Cheat Sheet

Keep these facts handy while extracting hours from dates.

TopicDetail
TypeAggregation date expression (not a find filter alone)
Simple syntax{ $hour: "$at" }
With timezone{ $hour: { date: "$at", timezone: "+05:30" } }
Range0 (midnight) to 23 (11 PM)
Default zoneUTC
Not allowedPlain date strings — convert to Date first
SampleISODate("…T14:00:00Z") → 14

Live Preview

Pick a UTC time and see $hour in UTC, then with offset +05:30.

Simulates default UTC $hour and $hour with timezone: "+05:30".

Result
at = 2024-06-15T08:15:00Z
$hour (UTC) → 8
$hour (+05:30) → 13

{ hourUtc: 8, hourIst: 13 }

Worked Walkthrough — UTC vs +05:30

Same instant, two hour readings: default UTC, then India Standard Time offset +05:30.

Calculation
at = 2024-06-15T08:15:00Z

UTC hour:
  08:15 → hour = 8

+05:30 hour:
  08:15 + 5h30m = 13:45
  hour = 13

Another check — 23:30Z + 05:30:
  23:30 + 5h30m = 05:00 (next calendar day)
  hour = 5

Timezone changes the clock face, not the stored instant.

MongoDB Examples

We use a small events collection with UTC dates. First we extract the UTC hour, then we extract the hour in +05:30. Insert the sample data once in mongosh.

Example 1 — Sample Data

Imagine three events on the same day, stored as BSON dates in UTC. We save them in a collection named events.

mongosh
db.events.insertMany([
  { _id: 1, name: "Standup", at: ISODate("2024-06-15T08:15:00Z") },
  { _id: 2, name: "Demo",    at: ISODate("2024-06-15T14:00:00Z") },
  { _id: 3, name: "Deploy",  at: ISODate("2024-06-15T23:30:00Z") }
]);

How the Data Is Stored in MongoDB

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

mongosh
db.events.find()

Read those documents like this:

Field in MongoDBExamplePlain English
_id1Event id for this lesson
name"Standup"Event label
atISODate("…T08:15:00Z")Event time as a BSON Date (UTC)
Picture
UTC day clock (hour hand):

  00  08  14  23
  |---|---|---|
      ^   ^   ^
   Standup Demo Deploy

  $hour("$at") → 8, 14, 23

How It Works

  1. Insert once. insertMany adds three event documents with real Date values.
  2. MongoDB stores Date, not string. ISODate(...) becomes a BSON Date—required by $hour.
  3. find() shows the same shape. What you inserted is what you get back—ready for $hour next.

Example 2 — Hour in UTC

Goal: add hourUtc using the simple { $hour: "$at" } form (UTC by default).

mongosh
db.events.aggregate([
  {
    $addFields: {
      hourUtc: { $hour: "$at" }
    }
  }
]);

How It Works

  1. Read the date. "$at" is the BSON Date for each event.
  2. Take the UTC hour. Minutes are ignored for the hour number (08:15 → 8).
  3. Range check. Results are 8, 14, and 23—all inside 0–23.
  4. Keep all fields. $addFields adds hourUtc next to the original document.

Example 3 — Hour with Timezone

Same events, but report the hour in +05:30 (for example India Standard Time).

mongosh
db.events.aggregate([
  {
    $addFields: {
      hourIst: {
        $hour: {
          date: "$at",
          timezone: "+05:30"
        }
      }
    }
  }
]);

How It Works

  1. Same stored dates. Still the three UTC instants from Example 1.
  2. Shift the clock. timezone: "+05:30" adds five and a half hours for the hour reading.
  3. Day wrap. Deploy at 23:30Z becomes 05:00 local → hour 5.
  4. Olson names work too. You could use "Asia/Kolkata" instead of "+05:30" when you prefer named zones.

Edge Cases & Pitfalls

Check these before using $hour in production pipelines.

type

Strings are not dates

$hour rejects plain strings. Convert with a date operator first, then extract the hour.

utc

Default is UTC

If users think in local time, set timezone. Forgetting it is a common off-by-hours bug.

dst

Named zones follow DST

Olson ids like "America/New_York" change with daylight saving. Fixed offsets like "+05:30" do not.

null

Missing dates

Null or missing date fields typically yield null. Guard with $ifNull if you need a default.

Performance Notes

ApproachCostBest for
$hour alonePer-document extractLabels, reports, grouping by hour
+ timezoneSmall conversion costLocal-hour analytics
Filter on raw DateIndex-friendlyRange queries before extracting parts

Prefer filtering on the Date field with $match when possible, then extract $hour for display or grouping. Computed hours alone are harder to index.

Key Takeaways

  • Role: extract hour 0–23 from a date.
  • Default: UTC unless you set timezone.
  • Input: Date / Timestamp / ObjectId — not a string.
  • Siblings: $minute, $second, $dateToParts.

One line: $hour answers “what hour is this date?”—0–23, UTC by default, optional timezone.

Frequently Asked Questions

$hour returns an integer from 0 to 23 for the hour portion of a date. For example, 2:30 PM UTC returns 14. Use it inside aggregation expression stages such as $project and $addFields.
Simple form: { $hour: <dateExpression> }. With timezone: { $hour: { date: <dateExpression>, timezone: <tz> } }. The date must be a Date, Timestamp, or ObjectId—not a string.
By default, $hour uses UTC. Pass timezone (Olson name or UTC offset) to get the hour in another zone.
No. Convert strings to dates first (for example with $dateFromString or $toDate), then pass that date to $hour.
$hour returns 0–23 for the hour. $minute returns 0–59 for the minute. Both extract one part of a date.
Yes for the default UTC behavior. Think of $hour as MongoDB’s aggregation version of Date.getUTCHours—unless you set timezone.

Next: $ifNull

Replace null or missing values with a default expression.

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