5 Ways to Get the Hour from a Date in MongoDB

MongoDB provides a good range of aggregation pipeline operators for working with dates, including operators that extract certain parts of dates, such as the year, month, day, hours, minutes, etc.

There are also a couple of MongoDB methods that enable you to iterate through a cursor, and apply a JavaScript function. You can therefore use JavaScript to extract date values and date parts, etc from a field as required.

This article presents 5 ways to return the hour portion from a Date object in MongoDB.

Sample Data

Suppose we have a collection called cats with the following documents:

{ "_id" : 1, "name" : "Scratch", "born" : ISODate("2021-01-03T23:30:15.123Z") }
{ "_id" : 2, "name" : "Meow", "born" : ISODate("2019-12-08T04:00:12Z") }
{ "_id" : 3, "name" : "Fluffy", "born" : ISODate("2020-09-24T10:30:00Z") }

The following examples demonstrate various options for returning the hour portion from the born field of those documents.

The $hour Operator

The $hour operator is specifically designed to return a document with the hour portion of a given date.

We can run the following code to return the hour portion from the born field in the above document.

db.cats.aggregate(
  [
    {
      $project:
        {
          _id: 0,
          birthHour: { $hour: "$born" }
        }
    }
  ]
)

Result:

{ "birthHour" : 23 }
{ "birthHour" : 4 }
{ "birthHour" : 10 }

You can also specify the timezone when using the $hour operator.

See MongoDB $hour for more information and examples.

The $dateToString Operator

The $dateToString operator converts a date object to a string according to a user-specified format. The user can therefore specify that just the hour portion is returned if required.

There are format specifiers for each date part. The %H format specifier returns the hour.

Example:

db.cats.aggregate(
   [
     {
       $project: {
         _id: 0,
          birthHour: { $dateToString: { format: "%H", date: "$born" } }
       }
     }
   ]
)

Result:

{ "birthHour" : "23" }
{ "birthHour" : "04" }
{ "birthHour" : "10" }

We could have provided more format specifiers to include date parts in the result, but seeing as we’re only interested in extracting the hour in this article, we only used one format specifier.

See MongoDB $dateToString for more information and examples.

The $dateToParts Operator

The $dateToParts operator returns a document that contains the constituent parts of a given BSON Date value as individual properties. The properties returned are year, month, day, hour, minute, second and millisecond.

We could therefore use $dateToParts in one pipeline stage, then add another pipeline stage that extracts the hour part.

Here’s what $dateToParts returns for our three documents:

db.cats.aggregate(
  [
    {
      $project:
        {
          _id: 0,
          dateParts: { $dateToParts: { date: "$born" } }
        }
    }
  ]
).pretty()

Result:

{
	"dateParts" : {
		"year" : 2021,
		"month" : 1,
		"day" : 3,
		"hour" : 23,
		"minute" : 30,
		"second" : 15,
		"millisecond" : 123
	}
}
{
	"dateParts" : {
		"year" : 2019,
		"month" : 12,
		"day" : 8,
		"hour" : 4,
		"minute" : 0,
		"second" : 12,
		"millisecond" : 0
	}
}
{
	"dateParts" : {
		"year" : 2020,
		"month" : 9,
		"day" : 24,
		"hour" : 10,
		"minute" : 30,
		"second" : 0,
		"millisecond" : 0
	}
}

This result can then be passed to the next stage in the pipeline to extract just the hour field.

Here’s what happens if we add another projection for just the hour field:

db.cats.aggregate(
  [
    {
      $project:
        {
          _id: 0,
          dateParts: { $dateToParts: { date: "$born" } }
        }
    },
    {
      $project:
        {
          birthHour: "$dateParts.hour"
        }
    }
  ]
)

Result:

{ "birthHour" : 23 }
{ "birthHour" : 4 }
{ "birthHour" : 10 }

The point here is, if you use $dateToParts in your pipeline, you automatically have access to the hour portion (and all other portions) in the next stage.

See MongoDB $dateToParts for more information and examples.

The forEach() Method

You can use cursor.forEach() to iterate through the cursor, using a JavaScript method such as getHours() or getUTCHours() to return just the hour value.

db.cats.find().forEach(
  function(c) {
    print(
      c.born.getUTCHours()
      );
  }
);

Result:

23
4
10

The getUTCHours() JavaScript method returns an integer, between 0 and 23, representing the hours in the given date according to universal time.

You may also notice that the previous options return a whole document that contains a name/value pair, whereas this option returns just the actual hour value, and not the whole document.

The map() Method

The cursor.map() method applies a function to each document visited by the cursor and combines the values into an array.

Example:

db.cats.find().map(
  function(c) {
    c = c.born.getHours();
    return c;
  }
);

Result:

[ 9, 14, 20 ]

You may have noticed that the resulting hours are different to the previous examples. That’s because in this example I used the getHours() JavaScript method. This method returns its result according to local time. I could just as easily have used getUTCHours().