Number of weeks in a month
Find the number of calendar weeks in the month containing a specific ISO date. Enter a date in YYYY-MM-DD form and choose which weekday starts the week.
Run — free
The result accounts for the month length, leap years, and the blank positions before the first day, so it reports the number of rows that month occupies on a conventional calendar. Every calculation uses fixed Gregorian arithmetic associated with UTC rather than the device clock, locale settings, or daylight-saving rules, making the answer stable in browsers, APIs, spreadsheets, and automated workflows.
What a calendar week span means
A month does not contain an exact whole number of seven-day periods, and the common phrase “weeks in a month” can mean different things. This calculator counts calendar-week rows: the number of weekly blocks touched by at least one date in the selected month. It first locates the weekday of the month’s first day, measures the empty positions before that date under your chosen week start, adds the actual number of days in the month, and divides the occupied span into seven-day rows. Consequently, a 31-day month can occupy five or six calendar weeks depending on its starting weekday. A 28-day February can occupy four weeks when its first date aligns with the selected first weekday, but it can occupy five when it does not. This definition matches month-view calendars, staffing boards, classroom planners, and reporting grids. It is intentionally different from dividing the day count by seven, which describes duration but cannot tell you how many visual or operational week buckets the month crosses.
Choose the first weekday explicitly
The first_weekday field controls how week boundaries are drawn. Use 0 for Sunday, 1 for Monday, continuing through 6 for Saturday. Monday is the default because it is common in ISO-oriented business calendars, but the computation does not claim that one convention is universally correct. A Sunday-first retail schedule and a Monday-first office schedule may legitimately produce different counts for the same month because their row boundaries occur on different dates. The response echoes both the numeric setting and its English weekday name, as well as the weekday on which the month begins and the number of leading positions. Those details make the result easy to audit and help prevent silent convention mismatches between systems. The supplied date must be an explicit zero-padded YYYY-MM-DD value. Its day selects the containing month; changing the day while keeping the same year and month leaves the count unchanged. Invalid dates, including impossible leap days, are rejected instead of being normalized into another month.
Deterministic calendar arithmetic for automation
The calculation uses the proleptic Gregorian calendar for years 0001 through 9999. Leap years are divisible by four, except century years unless they are also divisible by 400. Weekdays are derived with integer arithmetic, and the implementation never reads the current clock, calls a network service, uses randomness, or invokes the JavaScript Date object. The UTC label therefore communicates a stable, timezone-neutral civil-date interpretation: the input is not shifted according to a server location or a user’s offset. This makes identical JSON produce identical output in the browser and API, including around daylight-saving transitions and near midnight. Use the result to size arrays of weekly report sections, reserve rows in printable schedules, validate an imported calendar layout, or determine how many week-based allocation buckets a monthly plan needs. The response also includes month length, month name, first-day weekday, and leading-day count, so downstream code can retain an explanation alongside the final weeks_in_month value. API requests start at $0.002, while the browser calculation follows the same deterministic core.
What you can do with it
Size a monthly calendar grid
Determine whether a month view needs four, five, or six week rows before rendering or printing it.
Build weekly staffing buckets
Create the correct number of weekly sections for a monthly rota under the organization’s week-start convention.
Validate reporting layouts
Check that generated monthly reports allocate every calendar week touched by at least one date.
FAQ
Does every month have four weeks?
No. Four weeks is exactly 28 days, but most months have more days and can span five or six calendar rows depending on alignment.
What does first_weekday mean?
It sets the boundary of each calendar week: 0 is Sunday, 1 is Monday, and values continue through 6 for Saturday.
Why can the same month have a different answer with another week start?
Changing the first weekday moves row boundaries, which can place the first and last dates across a different number of calendar-week rows.
Does the day in the input date affect the result?
It identifies and validates the containing month. Every valid date within the same year and month produces the same month-span count for a fixed week start.
How are leap years and timezones handled?
Gregorian leap-year rules are applied with integer arithmetic. No timezone conversion occurs, so the explicit civil date is interpreted consistently as a UTC-based calendar input.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/date/weeks-in-month \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"date":"2026-08-13"}'const res = await fetch("https://api.kit.forhosting.com/date/weeks-in-month", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"date": "2026-08-13"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/date/weeks-in-month",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"date": "2026-08-13"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/date/weeks-in-month", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"date":"2026-08-13"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"date":"2026-08-13"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/date/weeks-in-month", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"date": "2026-08-13"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "date.weeks_in_month",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |