Month difference between two dates in sql server
Calculating Month Difference Between Two Dates in SQL Server

Learn various methods to accurately calculate the difference in months between two dates in SQL Server, addressing common pitfalls like partial months and date boundaries.
Calculating the difference in months between two dates is a common requirement in SQL Server for reporting, analytics, and business logic. While SQL Server provides built-in functions like DATEDIFF
, understanding its nuances and alternative approaches is crucial for accurate results, especially when dealing with partial months or specific business rules. This article explores different techniques, their advantages, and potential issues.
Understanding DATEDIFF for Month Differences
The DATEDIFF
function is the most straightforward way to find the difference between two dates in SQL Server. When used with the month
datepart, it counts the number of month boundaries crossed between the startdate
and enddate
. However, it's important to note that DATEDIFF(month, startdate, enddate)
only counts full month boundaries. It does not consider partial months or the day of the month.
SELECT
DATEDIFF(month, '2023-01-15', '2023-02-14') AS MonthsDiff1, -- Output: 1
DATEDIFF(month, '2023-01-15', '2023-02-15') AS MonthsDiff2, -- Output: 1
DATEDIFF(month, '2023-01-31', '2023-02-01') AS MonthsDiff3, -- Output: 1
DATEDIFF(month, '2023-01-01', '2023-01-31') AS MonthsDiff4; -- Output: 0
Basic usage of DATEDIFF(month) in SQL Server
DATEDIFF(month, startdate, enddate)
only counts month boundaries. If you need to consider partial months or the day of the month for a 'full month' calculation, DATEDIFF
alone might not suffice.Calculating Full Months (Day-Aware Difference)
Often, the business requirement is to count 'full months' where a month is only considered complete if the end date's day is greater than or equal to the start date's day. For example, from January 15th to February 14th is 0 full months, but from January 15th to February 15th is 1 full month. This requires a more complex calculation.
DECLARE @StartDate DATE = '2023-01-15';
DECLARE @EndDate DATE = '2023-02-14';
SELECT
CASE
WHEN DAY(@EndDate) >= DAY(@StartDate) THEN DATEDIFF(month, @StartDate, @EndDate)
ELSE DATEDIFF(month, @StartDate, @EndDate) - 1
END AS FullMonthsDiff;
-- Example 2: Full month
SET @StartDate = '2023-01-15';
SET @EndDate = '2023-02-15';
SELECT
CASE
WHEN DAY(@EndDate) >= DAY(@StartDate) THEN DATEDIFF(month, @StartDate, @EndDate)
ELSE DATEDIFF(month, @StartDate, @EndDate) - 1
END AS FullMonthsDiff;
Calculating full months considering the day of the month
flowchart TD A[Start: Get StartDate, EndDate] B{Is DAY(EndDate) >= DAY(StartDate)?} C[Calculate DATEDIFF(month, StartDate, EndDate)] D[Subtract 1 from DATEDIFF result] E[End: Return Result] A --> B B -- Yes --> C B -- No --> D C --> E D --> E
Logic for calculating full months between two dates
Handling Edge Cases and Alternative Approaches
Edge cases often arise with date calculations, such as dates at the end of the month or leap years. Another approach involves manipulating the dates to align them before using DATEDIFF
to achieve specific 'full month' definitions. For instance, you might adjust the EndDate
to the same day of the month as StartDate
in the EndDate
's month, then compare.
DECLARE @StartDate DATE = '2023-01-31';
DECLARE @EndDate DATE = '2023-03-01'; -- Should be 1 full month (Jan 31 -> Feb 28/29)
SELECT
DATEDIFF(month, @StartDate, @EndDate) -
CASE
WHEN DAY(@StartDate) > DAY(@EndDate) AND DAY(@EndDate) < DAY(DATEADD(month, DATEDIFF(month, @StartDate, @EndDate), @StartDate)) THEN 1
ELSE 0
END AS AdjustedMonthsDiff;
-- More robust full month calculation (credit: Itzik Ben-Gan's approach)
SELECT
DATEDIFF(month, @StartDate, @EndDate) -
CASE
WHEN DATEADD(month, DATEDIFF(month, @StartDate, @EndDate), @StartDate) > @EndDate THEN 1
ELSE 0
END AS RobustFullMonthsDiff;
Advanced full month calculation addressing end-of-month scenarios