Months between two dates
Enter two dates to get the whole months between them plus the leftover days: from 2024-01-15 to 2025-03-10 is 13 months and 23 days. Month ends are handled, so January 31 plus one month is the end of February. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Start ISO date
- 2024-01-15
- End ISO date
- 2025-03-10
- From date
- 2024-01-15
- To date
- 2025-03-10
- Months
- 13
- Days
- 23
Contracts, tenancy schedules, infant age in months, subscription milestones, and project timelines often need more than a raw day count: they need how many whole calendar months fit between two dates, and how many days remain after those months. This months between two dates calculator accepts a pair of ISO calendar dates, validates each day under Gregorian leap-year rules with pure integer arithmetic, advances the earlier date month by month with end-of-month clamping, and returns a structured whole-months plus remaining-days result that forms, spreadsheets, and APIs can pin without reimplementing calendar edge cases. Invalid shapes and impossible dates such as February thirtieth fail with invalid input and are not charged.
Choosing from and to ISO dates and what formats are accepted
Send two string fields named from and to. Each value should be an ISO calendar date with a four-digit year, month, and day, for example two thousand twenty-four hyphen zero one hyphen fifteen. You may also send a full ISO-8601 datetime with hours, minutes, seconds, optional fractional seconds, a trailing Z for UTC, or a numeric offset such as plus zero two colon zero zero.
When a time is present, the engine validates the clock fields so impossible hours are rejected, but only the civil year-month-day part is used for whole-month and remaining-day math, which keeps the product honest for people who search for months between two dates rather than a second-level countdown. Years are limited to one through nine thousand nine hundred ninety-nine, months to one through twelve, and days must exist in that month including leap-year February twenty-ninth when applicable.
Anything outside those ranges is invalid input rather than silently rolled over into the next month.
What you can do with it
Age in months for infants and pediatrics
Health and parenting apps compute how many whole months and days have passed since a birth date without floating-point month averages or host timezone drift.
Subscription and project milestones
Billing and project dashboards measure tenure or phase length between two fixed ISO dates and flip copy with direction when a target date is already past.
FAQ
What happens if a date is invalid?
Bad ISO shape, impossible calendar days such as February 30, and out-of-range fields are rejected and not charged.
Is the months between two dates calculator free?
The browser tool runs free on your device.
Does this use the server wall clock or JavaScript Date?
No. Both dates come from your input strings. The engine uses pure Gregorian month arithmetic without Date, network, or randomness, so results are fully deterministic.
How are months counted when the start date is the 31st?
With month-end clamping: one month after January 31 is the last day of February, not a date in March. The tool advances month by month this way and counts the leftover days separately.
What if the end date comes before the start date?
You still get positive months and days for the span, plus a direction marked as backward and signed values carrying a minus sign, so you can tell that the target date has already passed.
Related tools
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/months-between \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"from":"2024-01-15","to":"2025-03-10"}'const res = await fetch("https://api.kit.forhosting.com/date/months-between", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"from": "2024-01-15",
"to": "2025-03-10"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/date/months-between",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"from": "2024-01-15",
"to": "2025-03-10"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/date/months-between", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"from":"2024-01-15","to":"2025-03-10"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"from":"2024-01-15","to":"2025-03-10"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/date/months-between", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"from": "2024-01-15",
"to": "2025-03-10"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "date.months_between",
"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. |
Technical notes
The path never touches the wall clock, randomness, or the network, so identical from and to strings always produce identical JSON in continuous integration and in production.
Choosing from and to ISO dates and what formats are accepted
Aliases start, begin, and start_date map to from; end, until, end_date, and target map to to, matching common form and API naming. Both fields are required: omitting either, sending a non-string, or passing empty whitespace raises invalid_input that names the missing side.
Reading months, days, total_days, signed fields, and direction
The fields months and days are always non-negative and together describe the absolute civil span: months is the largest whole-month count you can advance from the earlier date without passing the later date, using end-of-month clamping so thirty-first of January plus one month lands on the last day of February. The days field is the remaining civil day difference after that advance, so a span from mid-January to early March might report one month and a few dozen days rather than a pure day total alone. On success the response echoes the original from and to strings plus normalized from_date and to_date as YYYY-MM-DD. Field total_days is the absolute difference of civil day numbers between the two dates and is useful when you also need an unordered day count. When the end is earlier than the start, is_past is true, direction is backward, and signed_months plus signed_days_remainder carry a negative sign while months and days stay non-negative for display. When both dates match, is_zero is true, direction is zero, and every magnitude is zero. Use months and days for human copy, total_days for sorting by length, and direction when product language must say remaining versus overdue.
API usage, pricing, product workflows, and practical limits
Call the free in-browser months between two dates tool for tenancy calculators, baby age in months, contract anniversary checks, and classroom demos without installing moment libraries or timezone databases. Keep expectations honest: this product measures whole Gregorian calendar months and leftover days between two explicit dates; it does not invent today from the server clock, skip weekends as business months, or load public holiday calendars. Source inputs follow the same retention rules as other KIT parse items. Send a JSON body with required string fields from and to as ISO dates. Use the prepaid API when a billing system, HR tenure board, property platform, or project planner needs a stable contract under KIT balance at $0.002 per successful item; validation failures never consume balance after the engine rejects the request. Pair this endpoint with a countdown-between-two-dates style tool when you also need hours and seconds for a launch timer, or with a days-in-month calculator when you first validate February lengths before building schedules. Authors shipping SDKs can map months and days straight into two numeric widgets and drive overdue styling from is_past using the same response shape in every language binding.
Integration use cases
Tenancy and contract duration
Property and legal tools pass lease start and end ISO dates, show whole months plus leftover days on the summary page, and store total_days for sorting active contracts.
Technical questions
How do I get months between two dates?
Send JSON with from and to as ISO dates (for example from: "2024-01-15" and to: "2025-03-10"). The response includes months, days, total_days, and a formatted string.
What if the end is before the start?
months and days stay non-negative for the absolute span, signed_months and signed_days_remainder are negative, is_past is true, and direction is backward.