MongoDB $dayOfYear Operator

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 4 Examples
Date Operations

What You’ll Learn

The $dayOfYear operator extracts the day number within a year (1–366) from a BSON Date inside MongoDB aggregation pipelines. Use it for “day N of the year” analytics, seasonal reporting, cohort comparisons, and detecting trends across different years.

01

Extract Day Index

Date → integer 1–366.

02

Syntax

One date argument.

03

Leap Years

Up to 366.

04

UTC Default

Uses UTC calendar.

05

Use Cases

Seasonality.

06

Related Ops

$dayOfMonth, $dateTrunc.

Definition and Usage

In MongoDB’s aggregation framework, the $dayOfYear operator takes a date expression and returns an integer between 1 and 366. For example, $dayOfYear applied to ISODate("2024-01-01T00:00:00Z") returns 1, and ISODate("2024-12-31T00:00:00Z") returns 366 because 2024 is a leap year.

💡
Beginner Tip

$dayOfYear uses the UTC calendar. If your business reporting is based on a local timezone, derive a local date first (see Example 4).

📝 Syntax

The $dayOfYear operator takes a single date expression:

mongosh
{ $dayOfYear: <dateExpression> }

Syntax Rules

  • Argument — any expression that evaluates to a BSON Date (field, $$NOW, or literal).
  • Return value — integer from 1 to 366 (leap years can return 366).
  • Null input — returns null when the date is null or missing.
  • Use inside $project, $addFields, $set, $match (with $expr), or $group.

💡 $dayOfYear vs $dayOfMonth vs $dateTrunc

$dayOfYear — BSON Date → integer 1–366 (day index within year)
$dayOfMonth — BSON Date → integer 1–31 (day within month)
$dateTrunc — BSON Date → Date at period boundary (great for grouping)

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (date extraction)
ArgumentsOne date expression
Return typeInteger (1–366)
Leap yearsCan return 366
MongoDB version3.4+
From field
{ $dayOfYear: "$createdAt" }

Day index within year

Jan 1
{ $dayOfYear: ISODate("2024-01-01") }

Returns 1

In $project
{
  doy: { $dayOfYear: "$eventAt" }
}

Add computed field

First week
{ $lte: [
  { $dayOfYear: "$d" },
  7
]}

Day 1–7

Examples Gallery

Extract day-of-year values, filter early-year events, group activity by day index, and build timezone-aware day-of-year logic with $dayOfYear.

📚 Extract Day of Year from a Date Field

Use an events collection and compute the day index within the year from eventAt.

Sample Input Documents

Suppose you have an events collection with timestamps:

mongosh
[
  {
    "_id": ObjectId("609c26812e9274a86871bc6a"),
    "name": "Kickoff",
    "eventAt": ISODate("2024-01-01T09:00:00Z")
  },
  {
    "_id": ObjectId("609c26812e9274a86871bc6b"),
    "name": "Campaign",
    "eventAt": ISODate("2024-03-01T12:00:00Z")
  }
]

Example 1 — Add dayOfYear with $dayOfYear

Extract the day index within the year:

mongosh
db.events.aggregate([
  {
    $project: {
      name: 1,
      eventAt: 1,
      dayOfYear: { $dayOfYear: "$eventAt" }
    }
  }
])

How It Works

  • Jan 1 is always 1.
  • March 1, 2024 is day 61 because 2024 is a leap year (February has 29 days).
  • The result is an integer you can filter or group on.

📈 Practical Patterns

Seasonality filters, grouping, and timezone-aware day-of-year extraction.

Example 2 — Find Events in the First Week of the Year

Filter events where the day-of-year is 1 to 7:

mongosh
db.events.find({
  $expr: {
    $lte: [
      { $dayOfYear: "$eventAt" },
      7
    ]
  }
})

How It Works

Use $expr to run aggregation expressions inside find(). Replace 7 with 90 to filter “first quarter” style seasonal windows.

Example 3 — Group Signups by Day of Year (Within Each Year)

Analyze seasonality patterns (day 1..366) per year:

mongosh
db.users.aggregate([
  {
    $group: {
      _id: {
        year: { $year: "$createdAt" },
        dayOfYear: { $dayOfYear: "$createdAt" }
      },
      signups: { $sum: 1 }
    }
  },
  { $sort: { "_id.year": 1, "_id.dayOfYear": 1 } }
])

How It Works

If you group by day-of-year alone, you mix different years together. Include $year in _id when you want per-year trends.

Example 4 — Timezone-Aware Day of Year (Local Midnight)

Compute day-of-year based on a local timezone rather than UTC:

mongosh
db.events.aggregate([
  {
    $addFields: {
      localParts: {
        $dateToParts: {
          date: "$eventAt",
          timezone: "America/Los_Angeles"
        }
      }
    }
  },
  {
    $addFields: {
      localDate: {
        $dateFromParts: {
          year: "$localParts.year",
          month: "$localParts.month",
          day: "$localParts.day",
          timezone: "America/Los_Angeles"
        }
      }
    }
  },
  {
    $project: {
      name: 1,
      eventAt: 1,
      dayOfYearLocal: { $dayOfYear: "$localDate" }
    }
  }
])

How It Works

$dayOfYear itself is UTC-based. This pattern first converts the instant into local calendar components, then rebuilds a local date so the day-of-year matches local midnight boundaries.

🚀 Use Cases

  • Seasonality analysis — compare activity by day index across years.
  • Campaign planning — measure performance around holidays or seasonal peaks.
  • Time-window filters — pick “first N days” or “last N days” of the year.
  • Data quality checks — validate expected patterns such as end-of-year processing (days 360+).

🧠 How $dayOfYear Works

1

MongoDB resolves the date

The input expression is evaluated per document — a field, $$NOW, or literal ISODate.

Input
2

$dayOfYear counts days in the year

MongoDB maps the date to a day index in the UTC calendar (1 through 365/366).

Extract
3

An integer is returned

The number is ready for $match, $group, or charts.

Output
=

Day index for analytics

Combine with $year, $dateTrunc, and $dayOfMonth for richer calendar reporting.

Conclusion

The $dayOfYear operator is a simple way to extract an easy-to-group day index from BSON dates in MongoDB aggregation pipelines. It is especially useful for seasonality analytics and “day N of the year” comparisons across different years.

Remember it uses UTC. If your use case depends on a local calendar, derive a local date before calling $dayOfYear. Next in the series: $degreesToRadians.

💡 Best Practices

✅ Do

  • Include $year when grouping by day-of-year to avoid mixing years
  • Use UTC consistently unless business logic requires local calendars
  • Remember leap years can produce day 366
  • Use $expr when filtering by $dayOfYear in find()
  • Prefer BSON dates over strings for reliable extraction

❌ Don’t

  • Assume local day-of-year matches UTC near midnight boundaries
  • Group by day-of-year alone when you need per-year trends
  • Confuse $dayOfYear with $dayOfMonth
  • Use $dayOfYear on string dates — parse first with $dateFromString
  • Use day-of-year as a unique identifier without the year

Key Takeaways

Knowledge Unlocked

Five things to remember about $dayOfYear

Use these points when extracting day-of-year values in MongoDB.

5
Core concepts
📝 02

One Argument

Date expression.

Syntax
🛠 03

Integer Output

Not a Date.

Output
🌐 04

UTC Calendar

Default timezone.

Note
05

Include Year

Don’t mix years.

Important

❓ Frequently Asked Questions

$dayOfYear returns an integer from 1 to 366 representing the day number within the year for a BSON Date. For example, January 1 returns 1, and December 31 returns 365 (or 366 in leap years).
{ $dayOfYear: <dateExpression> }. Pass a field reference like "$createdAt", a literal ISODate, or another expression that evaluates to a date.
$dayOfYear extracts the day-of-year using the UTC calendar. If you need a timezone-aware day-of-year (based on local midnight), derive a local date using $dateToParts + timezone and rebuild it with $dateFromParts before calling $dayOfYear.
$dayOfYear returns a single integer (1–366). $week returns a week number, and $dateTrunc returns a Date at a period boundary (like start of day or month) which is great for grouping.
$dayOfYear is available in MongoDB 3.4 and later in aggregation pipelines and update pipelines that use aggregation expressions.

Continue the Operator Series

Move on to $degreesToRadians for math conversions, or review $dateTrunc to bucket dates into time periods.

Next: $degreesToRadians →

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