JavaScript Date setMonth() Method

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Month index (0–11)

What You’ll Learn

setMonth() writes the calendar month (0–11) on a Date in local time, with an optional day-of-month. This guide covers zero-indexed months, end-of-month overflow, and relative month shifts.

01

Syntax

setMonth(m)

02

0–11

Jan = 0

03

Day arg

Optional

04

Overflow

Jan 31 trap

05

+ months

getMonth + n

06

Returns

Epoch ms

Introduction

Billing cycles, subscription renewals, and “three months from today” rules need to change the month on a Date. After reading the month with getMonth(), setMonth() writes it back in local time.

Months are zero-indexed: January is 0, December is 11. Like other setters, setMonth() mutates the Date and returns epoch milliseconds—not the Date for chaining.

Understanding the setMonth() Method

Date.prototype.setMonth(monthIndex [, day]) accepts a month index and an optional day (1–31). When you omit day, the current day-of-month is kept—it does not reset to the 1st.

End-of-month dates can surprise you: Jan 31 plus February becomes March 3 in a non-leap year because February has only 28 days. For UTC month writes, use setUTCMonth().

💡
Beginner Tip

April = 3, not 4. To jump to June 15: date.setMonth(5, 15). To add three months: date.setMonth(date.getMonth() + 3).

📝 Syntax

JavaScript
dateObj.setMonth(monthIndex)
dateObj.setMonth(monthIndex, day)

Parameters

  • monthIndex — Integer 0–11 (January–December). Values outside range normalize into adjacent years.
  • day (optional) — Integer 1–31 for day-of-month. If omitted, the existing day is kept.

Return value

  • Updated epoch milliseconds after the change.
  • NaN if the Date was invalid before the call.

⚡ Quick Reference

GoalCode
Set to April (keep day)date.setMonth(3)
Set to June 15date.setMonth(5, 15)
Add 3 monthsdate.setMonth(date.getMonth() + 3)
Read month after setdate.getMonth()
Named constantconst APRIL = 3
Clone before mutateconst copy = new Date(date)

📋 setMonth() vs Similar Methods

Pick the setter that matches the calendar field and timezone you need.

setMonth()
local 0–11

Local month

getMonth()
read

Getter pair

setFullYear()
year

Year setter

setUTCMonth()
UTC 0–11

UTC setter

Examples Gallery

Open DevTools Console (F12) or use Try-it links. Examples use the Date constructor for predictable local calendar values.

📚 Getting Started

Change the month while keeping the day when possible.

Example 1 — Set Month to April (3) and Keep the Day

Start on February 15 and move to April 15.

JavaScript
const date = new Date(2026, 1, 15); // Feb 15, 2026
date.setMonth(3); // April

console.log(date.getMonth());  // 3
console.log(date.getDate());   // 15
Try It Yourself

How It Works

Month index 3 is April. With no day argument, the 15th is preserved.

📈 Practical Patterns

End-of-month overflow, combined month/day, relative shifts, and year rollover.

Example 2 — End-of-Month Overflow (Jan 31 → February)

February has fewer than 31 days, so the date rolls into March.

JavaScript
const date = new Date(2026, 0, 31); // Jan 31, 2026
date.setMonth(1); // February

console.log(date.getMonth());     // 2 (March — overflow)
console.log(date.getDate());      // 3
console.log(date.getFullYear());  // 2026
Try It Yourself

How It Works

Feb 2026 has 28 days. Day 31 overflows by 3 days into March 3. Use setMonth(1, 28) or the last day of month if you need to clamp instead.

Example 3 — Set Month and Day Together (setMonth(5, 15))

Jump directly to June 15 regardless of the previous calendar date.

JavaScript
const date = new Date(2026, 0, 1); // Jan 1, 2026
date.setMonth(5, 15); // June 15

console.log(date.getMonth());  // 5
console.log(date.getDate());   // 15
Try It Yourself

How It Works

The two-argument form sets both month index and day-of-month in one call.

Example 4 — Add Three Months (Clone First)

Schedule a renewal three months out while preserving the original Date.

JavaScript
const start = new Date(2026, 8, 10); // Sep 10, 2026
const renewal = new Date(start);
renewal.setMonth(renewal.getMonth() + 3);

console.log("Start month:", start.getMonth());      // 8
console.log("Renewal month:", renewal.getMonth());  // 11 (December)
Try It Yourself

How It Works

Clone before mutating when other code still needs the original instant. September + 3 months = December.

Example 5 — Month Index Overflow (setMonth(12))

Month index 12 normalizes into January of the next year.

JavaScript
const date = new Date(2026, 10, 20); // Nov 20, 2026
date.setMonth(12);

console.log(date.getMonth());     // 0 (January)
console.log(date.getFullYear());  // 2027
Try It Yourself

How It Works

Index 12 is one month past December (11), so the year increments and the month becomes January (0).

🚀 Common Use Cases

  • Subscription renewalssetMonth(getMonth() + 1) monthly billing.
  • Quarter shifts — add three months for quarterly reports.
  • Season pickers — map UI month names to 0–11 indices.
  • First-of-month snapssetMonth(m, 1) for billing anchors.
  • End-of-month caution — validate Jan 31 → Feb transitions.
  • Clone + mutate — keep originals when computing future dates.

🧠 How setMonth() Updates the Calendar

1

Read local date

Engine loads year, month index, and day-of-month.

Local
2

Apply new month

Month index and optional day replace old values.

setMonth
3

Normalize overflow

Invalid day/month combos roll into adjacent months or years.

Normalize
4

Mutate & return ms

Date updates in place; epoch milliseconds are returned.

📝 Notes

  • Months are zero-indexed: 0 = January, 11 = December.
  • Omitting day keeps the current day—it does not default to 1.
  • Jan 31 → February is a common overflow trap; test end-of-month dates.
  • Mutates the original Date—clone with new Date(date) when needed.
  • Returns epoch ms, not the Date—no fluent chaining on the return value.
  • Use setUTCMonth when rules follow UTC, not local wall calendar.

Browser & Runtime Support

Date.prototype.setMonth() has been available since ES1. It works in every browser and Node.js.

Baseline · ES1

Date.prototype.setMonth()

Supported in Chrome, Firefox, Safari, Edge, Internet Explorer, and all Node.js versions. No polyfill required.

99% Universal API
Google Chrome Supported · Desktop & Mobile
Full support
Mozilla Firefox Supported · Desktop & Mobile
Full support
Apple Safari Supported · macOS & iOS
Full support
Microsoft Edge Supported · Chromium
Full support
Internet Explorer No native support · Use a polyfill
Polyfill
Opera Supported · Modern versions
Full support
Samsung Internet Supported · Android
Full support
Bun Supported · JavaScript runtime
Supported
Deno Supported · JavaScript runtime
Supported
Node.js Supported · Server runtime
Supported
Android WebView Supported · Modern WebView
Full support
Date.setMonth() Excellent

Bottom line: Safe everywhere. Remember zero-indexed months, end-of-month overflow, and mutation.

Conclusion

setMonth() writes the local calendar month (0–11) and optionally the day on a JavaScript Date. Use it for renewals and season shifts; watch end-of-month overflow and clone when preserving the original date.

Next, learn setSeconds() to change the second component, or review getMonth() for reading the month index.

💡 Best Practices

✅ Do

  • Remember January = 0, December = 11
  • Use named constants (const APRIL = 3) for readability
  • Clone before mutating shared Date instances
  • Test Jan 31 and leap-year February transitions
  • Use setMonth(m, 1) when you need the first of a month

❌ Don’t

  • Pass human month numbers 1–12 without subtracting 1
  • Assume omitted day resets to the 1st
  • Chain setters on the numeric return value
  • Ignore overflow when moving from 31-day months
  • Mix local setters with UTC getters in one label

Key Takeaways

Knowledge Unlocked

Five things to remember about Date.setMonth()

Your foundation for local month writes in JavaScript.

5
Core concepts
🔢 02

0–11

Jan = 0.

Index
📅 03

Day kept

If omitted.

Default
04

Jan 31

Overflow trap.

Pitfall
05

+ months

getMonth + n.

Pattern

❓ Frequently Asked Questions

It sets the month index (0–11) of a Date object in local time. An optional day argument can also set the day-of-month. The Date mutates in place and returns updated epoch milliseconds.
JavaScript Date months are zero-indexed like getMonth(): 0 = January through 11 = December. April is index 3, not 4.
No. If you pass only the month index, the current day-of-month stays the same unless overflow normalization changes it (e.g. Jan 31 → February rolls into March).
February has fewer days than 31. JavaScript normalizes overflow—Jan 31, 2026 becomes March 3, 2026 (Feb 28 + 3 days).
No. It returns a number (epoch milliseconds). Call each setter on the same Date variable—do not chain on the return value.
setMonth() changes the local calendar month. setUTCMonth() changes the UTC calendar month. Use the one that matches your timezone rules.
Did you know?

Human month numbers (1–12) are not what setMonth() expects—subtract 1. And when you omit the day argument, the day stays put; only overflow (like Jan 31 → Feb) changes it.

Continue to setSeconds()

Learn how to set the seconds component (0–59) on a Date object in local time.

setSeconds() 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.

6 people found this page helpful