EDATE
ZELFDE.DAG in Dutch Excel
Returns the date that falls on the same day of the month a given number of months before or after a start date.
Last updated: 13 October 2026
| Row | A | B | C |
|---|---|---|---|
| 1 | Entry | Start date | Renewal |
| 2 | 25-0118 | 15 Mar 2025 | 15 Mar 202615 Mar 2026=EDATE(B2, 12)=EDATE(B2; 12) |
| 3 | 25-0231 | 1 Jul 2025 | |
| 4 | 25-0305 | 29 Feb 2024 | |
| 5 | 25-0377 | 31 Oct 2025 |
Swipe sideways to see all columns
Result: 15 Mar 2026
=EDATE(B2,12)
=EDATE(B2;12)
What EDATE does and when to use it
What it does: it moves a date by whole calendar months and keeps the day number, for example a policy that starts on 15 March runs out on 15 March a year later.
When to use it: for renewal dates, contract and probation end dates, and instalment dates. It replaces adding 30 days, which drifts because months differ in length. For the last day of a month use EOMONTH.
Two main gains:
- Calendar months: the day number stays, where adding 30 days drifts.
- Short months handled: a start on the 31st lands on the last day of a shorter month, with no error.
How Excel evaluates it
Excel reads start_date as a serial number and splits it into year, month and day. It cuts months to a whole number and adds it to the month, carrying into the next or previous year when the count passes December or January.
If the original day exists in the target month it keeps it; if not (day 31 in a 30-day month, day 29 to 31 in February), it uses the last day of that month. It returns the serial number of that date, such as 46461, so the cell needs a date format.
Watch out: When the target month is too short for the day, EDATE returns the last day of that month: January 31 plus 1 month is February 28 (or 29 in a leap year).
Mental model
Flip a wall calendar forward the number of pages and put your finger on the same square number; if that page has no such square, your finger goes to the last one.
Terms used on this page: serial number, cell
EDATE(start_date,months)
EDATE(start_date;months)
| Argument | Type | Meaning |
|---|---|---|
start_date | Required | The date to count from; its day number is kept where the month allows. |
months | Required | Months to move: 12 is a year later, -3 is three months back. |
Return value:The serial number of the same day, months later or earlier
Formulas use commas (,) between arguments, as in English Excel. Formulas use semicolons (;) between arguments, as in Dutch Excel. Formulas use commas (,) between arguments, as in English Excel; Dutch Excel uses semicolons (;).
Worked examples
Beginner
Renewal date of prepaid insurance policies
You test the prepaid expenses (vooruitbetaalde kosten) of Veldhuis Installatie BV at 31 December 2025. Four annual insurance premiums were booked as INK entries. Each policy runs for 12 months from its start date and renews on the same day of the month. You want the renewal date next to every entry, to see which premiums still cover a period after year end.
| Row | A | B | C | D |
|---|---|---|---|---|
| 1 | Entry | Start date | Renewal | |
| 2 | 25-0118 | 15 Mar 2025 | 15 Mar 202615 Mar 2026=EDATE(B2, 12)=EDATE(B2; 12) | |
| 3 | 25-0231 | 1 Jul 2025 | ||
| 4 | 25-0305 | 29 Feb 2024 | ||
| 5 | 25-0377 | 31 Oct 2025 | ||
| 6 |
Swipe sideways to see all columns
Formula in C2
=EDATE(B2,12)
=EDATE(B2;12)
Result: 15 Mar 2026
Step by step
- Excel reads
B2: 15 Mar 2025, serial number 45731. That is the start_date: year 2025, month 3, day 15. - months is 12, so it moves 12 calendar months forward: month 3 of 2025 becomes month 3 of 2026.
- March has 31 days, so day 15 exists and is kept. The result is 15 Mar 2026, serial number 46096. That is 46096 - 45731 = 365 days later.
C2has a date format, so it shows 15 Mar 2026 instead of 46096. This policy still covers 74 days after year end, so part of the premium belongs in prepaid expenses.Copy down:
25-0231: 1 Jul 2025 becomes 1 Jul 202625-0305: started on 29 Feb 2024, a leap day; February 2025 has 28 days, so EDATE returns 28 Feb 2025, before year end: nothing of that premium is prepaid25-0377: 31 Oct 2025 becomes 31 Oct 2026
Watch out: B2 + 365 gives the same answer here, but for a start date less than a year before a leap day, such as 1 Mar 2027 + 365, it lands on 29 Feb 2028 instead of 1 Mar. Use EDATE for anniversaries.
More on this example: why it works, 1 variation
Why it works
EDATE counts calendar months, not days, so a year later is the same date whether the year has 365 or 366 days. The leap-day policy shows the clamp: a day that does not exist in the target month becomes that month's last day, never a date in the next month.
Variations
=EDATE(B2,12) - 1
=EDATE(B2;12) - 1
The last day of cover, 14 Mar 2026, when the policy ends the day before the renewal.
Intermediate
Repayment dates of a bank loan that starts on the 31st
Veldhuis Installatie BV took a bank loan that was paid out on 31 August 2025. It is repaid in six monthly instalments of 4,0004.000, due on the same day of the month. Several months have no 31st.
You recalculate the due dates to agree them to the bank confirmation (bankbevestiging). The start date sits in E1 and the instalment number in column A; one formula, copied down, gives every due date.
| Row | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| 1 | Instalment | Amount | Due date | Loan start | 31 Aug 2025 | |
| 2 | 11 | €4,000.00€ 4.000,00 | 30 Sep 202530 Sep 2025=EDATE($E$1, A2)=EDATE($E$1; A2) | |||
| 3 | 22 | €4,000.00€ 4.000,00 | ||||
| 4 | 33 | €4,000.00€ 4.000,00 | ||||
| 5 | 44 | €4,000.00€ 4.000,00 | ||||
| 6 | 55 | €4,000.00€ 4.000,00 | ||||
| 7 | 66 | €4,000.00€ 4.000,00 | ||||
| 8 |
Swipe sideways to see all columns
Formula in C2
=EDATE($E$1,A2)
=EDATE($E$1;A2)
Result: 30 Sep 2025
Step by step
- Excel reads start_date from
$E$1: 31 Aug 2025, serial 45900. months comes fromA2: 1. - One month on is September 2025. September has 30 days, so day 31 does not exist and EDATE uses the last day: 30 Sep 2025, serial 45930.
- Copy down. C3 is EDATE($E$1, 2): two months from 31 Aug is October, which has a 31st, so 31 Oct 2025 (45961). The clamp in September did not carry over, because every row counts from E1.
C4toC7: 30 Nov (November has 30 days), 31 Dec 2025, 31 Jan and 28 Feb 2026. Each date is the 31st where it exists and the month end where it does not.- Compare chaining, where C3 is EDATE(C2, 1): it starts from 30 Sep and gives 30 Oct, then 30 Nov, 30 Dec and 30 Jan. Three due dates are a day early against the bank confirmation, with no error to warn you.
- Without the
$signs,C3would readE2, which is empty, and count from serial 0, a date in 1900. ChangeE1to 15 Aug 2025 and all six dates move to the 15th.
Watch out: If the instalment number in column A is blank, months is 0 and EDATE returns the start date itself, 31 Aug 2025, which looks like a valid due date.
More on this example: why it works, 1 more pitfall, 1 variation
Why it works
Counting every instalment from the same fixed start date with a growing months value means each date is calculated independently, so a short month affects only its own row. The locked reference to E1 is what makes the column a schedule instead of a chain.
More to watch out for
- A due date on a weekend is not moved: 30 Nov 2025 is a Sunday. If the bank collects on the next working day, check the bank statement against WORKDAY(date - 1, 1).
Variations
=EOMONTH($E$1,A2)
=EOMONTH($E$1;A2)
If the loan agreement says 'last day of each month' rather than 'the 31st', EOMONTH gives the same dates here; they differ as soon as the start is not a month end.
Advanced
Last day to give notice on a lease contract
You assess the lease term of the rented premises and vehicles of Veldhuis Installatie BV. The contract list gives a start date, a term in months and a notice period in months. A contract ends the day before its anniversary, and notice must be given no later than the notice period before that end date.
From the deadline you see whether the company could still terminate at year end 2025 or is committed to another term. You want the deadline in one formula, with the end date calculated inside it.
| Row | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| 1 | Contract | Start | Term (months) | Notice (months) | Notice deadline | |
| 2 | H-501 | 1 Sep 2025 | 1212 | 22 | 30 Jun 202630 Jun 2026=EDATE(EDATE(B2, C2) - 1, -D2)=EDATE(EDATE(B2; C2) - 1; -D2) | |
| 3 | H-502 | 1 Dec 2025 | 1212 | 33 | ||
| 4 | H-503 | 15 Jan 2025 | 2424 | 11 | ||
| 5 |
Swipe sideways to see all columns
Formula in E2
=EDATE(EDATE(B2,C2) - 1, -D2)
=EDATE(EDATE(B2;C2) - 1; -D2)
Result: 30 Jun 2026
Step by step
- Excel evaluates the inner EDATE first: EDATE(B2, C2) moves 1 Sep 2025 (serial 45901) forward 12 months to 1 Sep 2026 (serial 46266), the anniversary.
- Subtracting 1 gives the end date: 46266 - 1 = 46265, 31 Aug 2026.
- The outer EDATE moves that end date back by
D2months: -2. Two months before 31 Aug is June, which has only 30 days, so EDATE returns the last day of June: 30 Jun 2026, serial 46203. - Copy down.
H-502: anniversary 1 Dec 2026, end 30 Nov 2026 (46356), three months back is 30 Aug 2026 (46264).H-503: anniversary 15 Jan 2027, end 14 Jan 2027, one month back is 14 Dec 2026. - All three deadlines fall after 31 December 2025, so at year end the company could still terminate each contract in time. Change
D2to 3 and the deadline forH-501becomes 31 May 2026: three months before 31 Aug, and May has a 31st.
Watch out: EDATE(B2, C2 - D2) - 1 looks shorter and gives the same date for H-501, but for H-502 it gives 1 Sep 2026 - 1 = 31 Aug 2026, one day later than 30 Aug. Subtracting the day before or after moving changes the answer; follow the order of the contract wording.
More on this example: why it works, 1 more pitfall, 1 variation
Why it works
Each step matches a phrase in the contract: the inner EDATE is 'the term', minus 1 is 'ends the day before', and the outer EDATE with a negative months value is 'notice before the end'. Negative months clamp the same way positive ones do, which is why the deadline before 31 Aug lands on 30 Jun.
More to watch out for
H-502's deadline, 30 Aug 2026, is a Sunday. EDATE does not know about weekends; see the variation for the last working day.
Variations
=WORKDAY(EDATE(EDATE(B3,C3) - 1, -D3) + 1, -1)
=WORKDAY(EDATE(EDATE(B3;C3) - 1; -D3) + 1; -1)
The last working day on or before the deadline: for H-502, Sunday 30 Aug 2026 becomes Friday 28 Aug 2026. WORKDAY steps one working day back from the day after.
MasterExcel 2021 or later (This example needs Excel 2021 or later)
Expected posting dates of recurring invoices, kept on month ends
You test the completeness of recurring supplier invoices (INK) at Veldhuis Installatie BV. Each contract has a first invoice date and a number of monthly invoices. The policy in the contracts: an invoice dated on the last day of a month is dated on the last day of every following month.
EDATE alone fails that for a first invoice on 30 Sep, because it keeps day 30 and gives 30 Dec, not 31 Dec. One formula per contract spills the expected dates across the row, choosing EOMONTH for month-end starts and EDATE for the rest, so you can look each date up in the auditfile.
| Row | A | B | C | D | E | F | G | H |
|---|---|---|---|---|---|---|---|---|
| 1 | Contract | First invoice | Invoices | Expected invoice dates | ||||
| 2 | R-201 | 30 Sep 2025 | 44 | 31 Oct 2025=LET( start, B2, n, C2, k, SEQUENCE(1, n), monthEnd, start = EOMONTH(start, 0), IF(monthEnd, EOMONTH(start, k), EDATE(start, k)) )=LET( start; B2; n; C2; k; SEQUENCE(1; n); monthEnd; start = EOMONTH(start; 0); IF(monthEnd; EOMONTH(start; k); EDATE(start; k)) ) | 30 Nov 2025 | 31 Dec 2025 | 31 Jan 2026 | |
| 3 | R-202 | 15 Sep 2025 | 44 | |||||
| 4 | R-203 | 30 Jun 2025 | 44 | |||||
| 5 |
Swipe sideways to see all columns
Formula in D2
=LET( start,B2, n, C2, k, SEQUENCE(1, n), monthEnd, start = EOMONTH(start, 0), IF(monthEnd, EOMONTH(start, k), EDATE(start, k)) )
=LET( start;B2; n; C2; k; SEQUENCE(1; n); monthEnd; start = EOMONTH(start; 0); IF(monthEnd; EOMONTH(start; k); EDATE(start; k)) )
Result: 31 Oct 2025 | 30 Nov 2025 | 31 Dec 2025 | 31 Jan 202631 Oct 2025 | 30 Nov 2025 | 31 Dec 2025 | 31 Jan 2026
Step by step
- LET names the inputs: start is 30 Sep 2025 (serial 45930) and n is 4. k is SEQUENCE(1, 4), a row {1, 2, 3, 4}: the month offsets of the four invoices.
- monthEnd compares start with EOMONTH(start, 0), the last day of its own month. September 2025 ends on the 30th, 45930 = 45930, so monthEnd is TRUE.
- IF takes EOMONTH(start, k) for the whole row: the month ends 1 to 4 months on: 31 Oct (45961), 30 Nov, 31 Dec 2025 and 31 Jan 2026. They spill from D2 to G2.
- For comparison, EDATE(start, k) would have given 30 Oct, 30 Nov, 30 Dec and 30 Jan: EDATE keeps day 30, so only November is right, and only because it has 30 days. You would look for an invoice dated 30 Dec and miss the one dated 31 Dec.
- Copied to
D3,R-202starts on 15 Sep 2025, not a month end (30 Sep is), so IF takes EDATE: 15 Oct, 15 Nov, 15 Dec 2025 and 15 Jan 2026. - In
D4,R-203starts on 30 Jun 2025, the end of June, so it gets 31 Jul, 31 Aug, 30 Sep and 31 Oct. EDATE would have given 30 Jul, 30 Aug, 30 Sep and 30 Oct: right in September only.
Watch out: The mirror-image mistake is EOMONTH(start, k) for every contract. It is right for R-201 and R-203, so a test on those passes, but R-202 then expects invoices on 31 Oct, 30 Nov, 31 Dec instead of the 15th.
More on this example: why it works, 2 more pitfalls, 1 variation
Why it works
EDATE clamps only when the day does not exist, so a start on a short month's last day is read as 'day 30', not as 'month end'. Testing start = EOMONTH(start, 0) recovers the intent, and EOMONTH with the same offsets keeps those contracts on month ends. SEQUENCE produces all offsets at once, and LET names each piece so the policy reads in the formula.
Do not use this construction when the contract fixes a day number (invoice on the 30th) regardless of the start: then plain EDATE is the rule. The alternative for older Excel versions is one EDATE or EOMONTH per column with the offset in a header row; more cells to maintain, but no spill and no LET.
More to watch out for
- The spill needs
E2:G2empty, otherwiseD2shows #SPILL!. A contract with more invoices than free columns runs into the next column's data. - Passing a range instead of an array to months, such as EDATE(start, D1:G1), can return #VALUE! in Excel, because EDATE does not accept ranges in that argument. SEQUENCE returns an array, which works.
Variations
=EDATE(B2,SEQUENCE(1, C2))
=EDATE(B2;SEQUENCE(1; C2))
Plain EDATE for every contract: shorter, and correct when the contract says 'same day number'. R-201 then expects its invoices on the 30th of each month.
Common mistakes
| Symptom | Cause | Fix |
|---|---|---|
| A five-digit number instead of a date | The formula returns a five-digit number such as 46461 instead of a date. | The result is a serial number and is correct. Give the cell a date format. |
| Monthly dates drift: 15 Jan, 14 Feb, 16 Mar | Monthly dates built by adding 30 days drift: 15 Jan, 14 Feb, 16 Mar, 15 Apr. | Use EDATE(start, n), which moves by calendar months and keeps the 15th. |
| After February the 31st stays the 28th | Each instalment is built from the one before it, EDATE(C2, 1), and after a February the 31st has turned into the 28th for good. | Always count from the original start date: EDATE($E$1, n). The clamp then applies to one month only. |
Used in combinations
- Revenue per month for twelve months in one formulaTotal revenue for each of twelve months with one SUMIFS: SEQUENCE counts the months, EDATE turns each count into the first day of a month, and those dates become the criteria.Excel 2021 or later (This combination needs Excel 2021 or later)