Calculating the difference in months between two dates is a useful skill for C# developers. Having this knowledge helps us in tasks such as subscription management and tracking course durations. In this article, we learn how to use DateOnly, DateTime, and TimeSpan structs to calculate the difference in months between two dates for scenarios like these.

Let’s begin.

## Understanding Month Calculations

Month calculations are not as straightforward as they may seem. Calculating the difference in months between two dates is challenging due to varying month lengths and leap years.Â To overcome these challenges we create two methods: one for calculating the difference in complete months and another for calculating month differences including partial months.

It’s important to define what we mean by “complete months”. In this article, a “complete month” starts on a specific day of one month and extends to the day before the same date in the following month. For example, March 15, 2023, to April 14, 2023, is one complete month. Similarly, March 15, 2023, to May 14, 2023, represents two complete months.

## Calculate the Difference Between Two Dates in Complete Months

Let’s imagine we operate an e-learning platform and want to know how long each user has been a subscriber in complete months.

First, we establish the user’s subscription start date:

```var subscriptionStart = new DateOnly(2023, 5, 14);
var subscriptionEndDate = DateOnly.FromDateTime(DateTime.Today);```

Here, we create a `DateOnly` struct called `subscriptionStart` representing the date the user began their subscription. Next, we define `subscriptionEndDate` and set it to today’s date using `DateOnly.FromDateTime(DateTime.Today)`. The method `DateOnly.FromDateTime` is used to change a `DateTime` struct, which includes both date and time, into a `DateOnly` struct. That way, we can just focus on the date and not the time.

To learn more, check out our other articles DateTime Format In C# and DateOnly and TimeOnly in C#

### Implement the Calculation Method

With our start and end dates defined, we calculate the difference:Â

```public static int CalculateSubscriptionDuration(DateOnly subscriptionStart, DateOnly endDate)
{
if (subscriptionStart > endDate)
{
throw new ArgumentOutOfRangeException(nameof(subscriptionStart),
"The subscription start date must be before the end date.");
}

int months = (endDate.Year - subscriptionStart.Year) * 12 + endDate.Month - subscriptionStart.Month;

if (endDate.Day < subscriptionStart.Day - 1)
{
months--;
}

if (subscriptionStart.Day == 1 && DateTime.DaysInMonth(endDate.Year, endDate.Month) == endDate.Day)
{
months++;
}

return months;
}```

In the `CalculateSubscriptionDuration()` we first need to check whether the start date is after the end date since it would be pretty unusual to be subscribed for a negative number of months. If that’s the case, we will throw an `ArgumentOutOfRangeException`.

If our end date is indeed after the start date, then we are safe to initialize `months`. This variable represents the total months elapsed, in terms of years, with the formula `(endDate.Year - subscriptionStart.Year) * 12`. Then, we adjust for the additional months within the incomplete year using `+ endDate.Month - subscriptionStart.Month`.

However, since we are only calculating full months, it’s important to check if the `endDate.Day` is less than the day before the `subscriptionStart.Day` (that’s why we subtract 1). To do this, we use the `Day` property of the `DateOnly` struct which gives us an integer representing the particular day of the month. If it’s true, we should subtract one month.

To make sure we account for all complete months, we also consider situations where the subscription starts on the first day of the month and ends on the last day of a particular month. To do this, we first check if the start day is the first day of the month. Then, using the `DateTime.DaysInMonth()` method, we check if the total days in that month match the end date’s day. If they are equal, we add one more month to our count.

Lastly, we return the total number of months.

### Getting the Result

Now that we can calculate the total number of months, let’s see our code in action:

```int totalMonthsSubscribed = NumberOfMonthsBetweenTwoDates.CalculateSubscriptionDuration(
subscriptionStart, subscriptionEndDate);
Console.WriteLine(\$"User has been subscribed for {totalMonthsSubscribed} months.");```

Here, we initialize `totalMonthsSubscribed` using the `CalculateSubscriptionDuration()` method we just created.

Assuming today’s date is January 23, 2024, let’s see the output:

`User has been subscribed for 8 months.`

Now we can see how many months a user has been a subscriber of our e-learning site. But what if we wanted to know how many months, including partial months? For instance, this user subscribed on May 14, 2023, so they have been a subscriber for 8 months and 9 days, or approximately 8.35 months.Â

## Calculate the Difference Between Two Dates in Approximate Months

Let’s think back to our e-learning platform. Now, instead of wanting to know how long someone’s been a subscriber, we want to know how long one of our courses has been “live” on the site.

Course duration in this scenario is the total time in months (as a double) between two dates (`courseStart` and `courseEndDate`). Similar to before, we calculate one month as the span between the start date’s day and the date preceding that day in the following month.

```var courseStart = new DateTime(2023, 9, 12);
var courseEndDate = DateTime.Today;```

Similar to before, we need to initialize start and end dates. We utilize the `DateTime` constructor to initializeÂ `courseStart`, the date we first released our course (September 12, 2023). Then, we use `courseEndDate`Â to represent today’s date.

### Create the Method to Calculate the Difference in Months Between Two Dates

With both start and end dates defined, let’s look at how to calculate the approximate months between dates:

```public static double CalculateCourseDuration(DateTime courseStart, DateTime endDate)
{
var courseStartUtc = courseStart.ToUniversalTime();
var endDateUtc = endDate.ToUniversalTime();

if (courseStartUtc > endDateUtc)
{
throw new ArgumentOutOfRangeException(nameof(courseStart),
"The course start date must be before the end date.");
}

double totalDays = (endDateUtc - courseStartUtc).TotalDays;

}```

Here, we have a new method called `CalculateCourseDuration()`. First, we need to convert our `courseStart` and `endDate` into UTC to ensure the time zone is consistent throughout the calculation.

Then, just like we did in our subscription calculation example, we ensure the start date is after the end date, throwing an `ArgumentOutOfRangeException` if not.

Our next goal is to calculate the `totalDays` (including the start date, but excluding the end date) between the two dates. We start by subtracting `courseStartUtc` from `endDateUtc`, which results in a `TimeSpan` object. Then, we use the `TotalDays` property of the `TimeSpan` struct to get the entire duration between those two dates in days (represented as a double). This includes whole days and the fractional part of a day if any.

To learn more about `TimeSpan`, don’t miss our article TimeSpan in C#.

Finally, we return the total number of months between the two dates. This is done by dividing `totalDays` by the average number of days in a month. ToÂ calculate the average number of days in a month,Â we divide the average number of days per year `365.2425` (considering leap years) by `12` (the number of months in a year).Â

Now, let’s look at how we can use our method:Â

```double courseDuration = NumberOfMonthsBetweenTwoDates.CalculateCourseDuration(courseStart, courseEndDate);
Console.WriteLine(\$"This course has been online for {courseDuration:F2} months.");```

Here, we define `courseDuration` which uses our new method `CalculateCourseDuration()`.

Assuming today’s date is January 23, 2024, let’s see how many months our course has been on the platform:Â

`This course has been online for 4.37 months.`

Now we know approximately how many months our course has been “live”. This knowledge is useful to evaluate the course performance, assess its profitability, or even help plan content updates.

## Conclusion

The ability to calculate time differences between dates is a valuable skill in C#. By understanding the different techniques for month calculations, we can enhance the functionality and precision of our applications. Whether it’s for monitoring subscription durations or checking how long a course has been online, there are infinite use cases. Can you think of scenarios where these monthly calculation methods would be useful? Feel free to let us know in the comments below.