# Number of Days Between Two Dates
**Difficulty:** EASY
[External](https://leetcode.com/problems/number-of-days-between-two-dates)
Canonical: https://scaleengineer.com/dsa/problems/number-of-days-between-two-dates
**Patterns:** [Math](https://scaleengineer.com/dsa/patterns/math)
**Data structures:** String
**Companies:** [Accenture](https://scaleengineer.com/companies/accenture), [Optiver](https://scaleengineer.com/companies/optiver)
---
## Problem
Write a program to count the number of days between two dates.

The two dates are given as strings, their format is `YYYY-MM-DD` as shown in the examples.

**Example 1:**

**Input:** date1 = "2019-06-29", date2 = "2019-06-30"
**Output:** 1

**Example 2:**

**Input:** date1 = "2020-01-15", date2 = "2019-12-31"
**Output:** 15

**Constraints:**

* The given dates are valid dates between the years `1971` and `2100`.

# Approaches
## Day-by-Day Simulation
This brute-force approach involves starting from the earlier of the two dates and incrementing day by day until the later date is reached, while keeping a count of the days passed.
**Time:** O(N), where N is the number of days between the two dates. For dates far apart, this can be very slow. The maximum difference is between 1971 and 2100, which is about 130 years or ~47,500 days. · **Space:** O(1), as we only use a few variables to store the current date and the counter, regardless of the input.
**Pros:** Conceptually simple and easy to follow.; Does not require complex mathematical formulas.
**Cons:** Inefficient for dates that are far apart.; The implementation of date advancement logic (handling month/year rollovers and leap years) can be tricky and prone to errors.
### Explanation
First, the two date strings are parsed to extract their year, month, and day components. We then determine which date is earlier to establish a starting point and an ending point. A counter is initialized to zero. We then enter a loop that continues as long as our current date is not the same as the end date. In each iteration of the loop, we advance the current date by one day and increment our counter. The logic for advancing the date must correctly handle month-ends and year-ends, including the special case of leap years for February. For example, when advancing from '2020-02-28', the next day is '2020-02-29' because 2020 is a leap year. When advancing from '2019-12-31', the next day is '2020-01-01'. Once the loop finishes, the counter holds the total number of days between the two dates.

```java
class Solution {
    public int daysBetweenDates(String date1, String date2) {
        // Ensure date1 is the earlier date
        if (date1.compareTo(date2) > 0) {
            String temp = date1;
            date1 = date2;
            date2 = temp;
        }

        int[] d1 = parseDate(date1);
        int[] d2 = parseDate(date2);

        int days = 0;
        while (d1[0] != d2[0] || d1[1] != d2[1] || d1[2] != d2[2]) {
            d1 = getNextDay(d1);
            days++;
        }
        return days;
    }

    private int[] parseDate(String date) {
        String[] parts = date.split("-");
        return new int[]{Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2])};
    }

    private int[] getNextDay(int[] date) {
        int year = date[0];
        int month = date[1];
        int day = date[2];

        day++;
        if (day > daysInMonth(year, month)) {
            day = 1;
            month++;
            if (month > 12) {
                month = 1;
                year++;
            }
        }
        return new int[]{year, month, day};
    }

    private int daysInMonth(int year, int month) {
        int[] days = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if (month == 2 && isLeap(year)) {
            return 29;
        }
        return days[month];
    }

    private boolean isLeap(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
}
```
### Algorithm
- Parse the input strings `date1` and `date2`.
- Ensure `date1` is the earlier date by swapping if necessary.
- Initialize a counter `days` to 0.
- Loop while `date1` is not equal to `date2`:
  - Advance `date1` to the next calendar day.
  - Increment the `days` counter.
- Return the final `days` count.

## Calculate Days from a Fixed Epoch
This optimal approach calculates the total number of days for each date from a fixed reference point (an 'epoch'), such as 1971-01-01. The absolute difference between these two counts gives the number of days between the dates. This avoids day-by-day iteration and results in a constant-time solution.
**Time:** O(1). Although the `countDaysSinceEpoch` function has loops, the number of iterations is bounded by the problem constraints (years from 1971 to 2100, months from 1 to 12). Therefore, the computation time is constant for any valid input dates. · **Space:** O(1). The space used is constant, consisting of a few variables and a small, fixed-size array for the number of days in each month.
**Pros:** Highly efficient with constant time complexity.; Scales perfectly, as the calculation time is independent of the distance between the dates.
**Cons:** The logic for counting days from an epoch can be slightly more complex to implement correctly from scratch compared to a simple simulation.
### Explanation
The main idea is to create a helper function that can convert any given date into a single number representing the total days that have passed since a fixed point in time. We can choose the epoch to be 1971-01-01, the beginning of the allowed range.

The function, let's call it `countDaysSinceEpoch(year, month, day)`, works as follows:
1.  **Sum days for full years:** It first calculates the total number of days from the epoch year (1971) up to the year just before the input `year`. It does this by iterating through these years and adding 365 for a common year and 366 for a leap year.
2.  **Sum days for full months:** Next, it adds the days for the completed months within the input `year`. It iterates from month 1 to `month - 1`, adding the correct number of days for each month (e.g., 31 for January, 28 or 29 for February depending on whether it's a leap year, etc.).
3.  **Sum days in the current month:** Finally, it adds the `day` of the month.

After implementing this function, we parse both input dates, call the function for each to get their respective day counts from the epoch, and then find the absolute difference of these two counts. This gives us the final answer.

```java
class Solution {
    private int[] daysInMonth = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    public int daysBetweenDates(String date1, String date2) {
        return Math.abs(countDaysSinceEpoch(date1) - countDaysSinceEpoch(date2));
    }

    private int countDaysSinceEpoch(String date) {
        String[] parts = date.split("-");
        int year = Integer.parseInt(parts[0]);
        int month = Integer.parseInt(parts[1]);
        int day = Integer.parseInt(parts[2]);

        int totalDays = 0;

        // 1. Add days for full years since epoch (1971)
        for (int y = 1971; y < year; y++) {
            totalDays += isLeap(y) ? 366 : 365;
        }

        // 2. Add days for full months in the current year
        for (int m = 1; m < month; m++) {
            totalDays += daysInMonth[m];
            if (m == 2 && isLeap(year)) {
                totalDays++;
            }
        }

        // 3. Add days in the current month
        totalDays += day;

        return totalDays;
    }

    private boolean isLeap(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
}
```
### Algorithm
- Create a helper function `countDaysSinceEpoch(date)` that calculates the total number of days from a fixed epoch (e.g., 1971-01-01) to the given `date`.
  - Sum the days for all full years between the epoch year and the given date's year, accounting for leap years (366 days) and common years (365 days).
  - Sum the days for all full months in the given year, before the given month. Account for leap years for February.
  - Add the day of the month.
- Parse `date1` and `date2`.
- Call `countDaysSinceEpoch` for both dates to get `totalDays1` and `totalDays2`.
- Return the absolute difference: `abs(totalDays1 - totalDays2)`.

# Solutions
### Java

```java
class Solution {
public
  int daysBetweenDates(String date1, String date2) {
    return Math.abs(calcDays(date1) - calcDays(date2));
  }
private
  boolean isLeapYear(int year) {
    return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
  }
private
  int daysInMonth(int year, int month) {
    int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    days[1] += isLeapYear(year) ? 1 : 0;
    return days[month - 1];
  }
private
  int calcDays(String date) {
    int year = Integer.parseInt(date.substring(0, 4));
    int month = Integer.parseInt(date.substring(5, 7));
    int day = Integer.parseInt(date.substring(8));
    int days = 0;
    for (int y = 1971; y < year; ++y) {
      days += isLeapYear(y) ? 366 : 365;
    }
    for (int m = 1; m < month; ++m) {
      days += daysInMonth(year, m);
    }
    days += day;
    return days;
  }
}

```

### CPP

```cpp
class Solution {
public:
  int daysBetweenDates(string date1, string date2) {
    return abs(calcDays(date1) - calcDays(date2));
  }
  bool isLeapYear(int year) {
    return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
  }
  int daysInMonth(int year, int month) {
    int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    days[1] += isLeapYear(year);
    return days[month - 1];
  }
  int calcDays(string date) {
    int year = stoi(date.substr(0, 4));
    int month = stoi(date.substr(5, 2));
    int day = stoi(date.substr(8, 2));
    int days = 0;
    for (int y = 1971; y < year; ++y) {
      days += 365 + isLeapYear(y);
    }
    for (int m = 1; m < month; ++m) {
      days += daysInMonth(year, m);
    }
    days += day;
    return days;
  }
};

```

### Python

```python
class Solution:
    def daysBetweenDates(self, date1: str, date2: str) -> int: def isLeapYear(year: int) -> bool: return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) def daysInMonth(year: int, month: int) -> int: days = [31, 28 + int(isLeapYear(year)), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, ] return days[month - 1] def calcDays(date: str) -> int: year, month, day = map(int, date . split("-")) days = 0 for y in range(1971, year): days += 365 + int(isLeapYear(y)) for m in range(1, month): days += daysInMonth(year, m) days += day return days return abs(calcDays(date1) - calcDays(date2))

```
