Count the Days Between Two Dates
Company: Optiver
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Take-home Project
# Count the Days Between Two Dates
You are given two calendar dates as strings in `YYYY-MM-DD` format. Return the number of days between them as a non-negative integer.
You must compute the result **without using any built-in date/time or calendar library** (e.g., no `datetime`, `java.time`, `Date`, or similar). The only calendar knowledge you may rely on is the standard Gregorian calendar rules given below. Assume a helper that returns the number of days in a given month is something you write yourself.
## Calendar rules
- Months have the usual lengths: January 31, February 28 (29 in a leap year), March 31, April 30, May 31, June 30, July 31, August 31, September 30, October 31, November 30, December 31.
- A year is a **leap year** if it is divisible by 4, **except** years divisible by 100, **unless** they are also divisible by 400. So 2000 and 2024 are leap years; 1900 and 2100 are not.
## Input
- `date1`: a string in `YYYY-MM-DD` format.
- `date2`: a string in `YYYY-MM-DD` format.
Both dates are guaranteed to be valid calendar dates between `1900-01-01` and `2100-12-31` inclusive. The dates may be given in either order (`date1` is not necessarily earlier than `date2`).
## Output
Return a single integer: the absolute difference in days between the two dates. If the dates are equal, return `0`.
## Examples
| date1 | date2 | Output | Explanation |
|-------|-------|--------|-------------|
| `2019-06-29` | `2019-06-30` | `1` | Consecutive days. |
| `2019-12-31` | `2020-01-15` | `15` | Crosses a year boundary. |
| `2020-02-28` | `2020-03-01` | `2` | 2020 is a leap year, so February 29 lies between them. |
| `2019-02-28` | `2019-03-01` | `1` | 2019 is not a leap year. |
| `2021-07-04` | `2021-07-04` | `0` | Same date. |
## Constraints
- `1900-01-01 <= date1, date2 <= 2100-12-31`
- Both inputs are valid dates in `YYYY-MM-DD` format.
- No date/time library calls are allowed; leap-year handling must be implemented from the rules above.
Quick Answer: This question evaluates date arithmetic, calendar logic, string parsing, and correct leap-year handling as implementation competencies. It is commonly asked to assess algorithmic correctness and edge-case handling across month, year, and leap boundaries, falls under the Coding & Algorithms domain (date/calendar problems), and targets practical application rather than purely conceptual understanding.
You are given two calendar dates as strings in `YYYY-MM-DD` format. Return the number of days between them as a non-negative integer.
You must compute the result **without using any built-in date/time or calendar library** (no `datetime`, `java.time`, `Date`, or similar). The only calendar knowledge you may rely on is the standard Gregorian calendar rules below; write your own helper for the number of days in a month.
## Calendar rules
- Month lengths: Jan 31, Feb 28 (29 in a leap year), Mar 31, Apr 30, May 31, Jun 30, Jul 31, Aug 31, Sep 30, Oct 31, Nov 30, Dec 31.
- A year is a **leap year** if it is divisible by 4, **except** years divisible by 100, **unless** they are also divisible by 400. So 2000 and 2024 are leap years; 1900 and 2100 are not.
## Input
- `date1`: a string in `YYYY-MM-DD` format.
- `date2`: a string in `YYYY-MM-DD` format.
Both dates are valid calendar dates between `1900-01-01` and `2100-12-31` inclusive, and may be given in either order (`date1` is not necessarily earlier than `date2`).
## Output
Return a single integer: the absolute difference in days between the two dates. If the dates are equal, return `0`.
## Examples
| date1 | date2 | Output |
|-------|-------|--------|
| `2019-06-29` | `2019-06-30` | `1` |
| `2019-12-31` | `2020-01-15` | `15` |
| `2020-02-28` | `2020-03-01` | `2` |
| `2019-02-28` | `2019-03-01` | `1` |
| `2021-07-04` | `2021-07-04` | `0` |
Constraints
- 1900-01-01 <= date1, date2 <= 2100-12-31
- Both inputs are valid dates in YYYY-MM-DD format.
- date1 is not necessarily earlier than date2.
- No date/time library calls are allowed; leap-year handling must be implemented from the Gregorian rules.
Examples
Input: ('2019-06-29', '2019-06-30')
Expected Output: 1
Explanation: Consecutive days.
Input: ('2019-12-31', '2020-01-15')
Expected Output: 15
Explanation: Crosses a year boundary.
Input: ('2020-02-28', '2020-03-01')
Expected Output: 2
Explanation: 2020 is a leap year, so Feb 29 lies between them.
Input: ('2019-02-28', '2019-03-01')
Expected Output: 1
Explanation: 2019 is not a leap year, so there is no Feb 29.
Input: ('2021-07-04', '2021-07-04')
Expected Output: 0
Explanation: Same date returns 0.
Input: ('2019-06-30', '2019-06-29')
Expected Output: 1
Explanation: Reversed order still yields the absolute difference.
Input: ('1900-01-01', '2100-12-31')
Expected Output: 73413
Explanation: Full supported range span; exercises the century non-leap years 1900 and 2100 and the leap century 2000.
Input: ('2000-02-28', '2000-03-01')
Expected Output: 2
Explanation: 2000 is divisible by 400, so it IS a leap year and Feb 29 exists.
Input: ('1900-02-28', '1900-03-01')
Expected Output: 1
Explanation: 1900 is divisible by 100 but not 400, so it is NOT a leap year.
Input: ('2023-12-31', '2024-12-31')
Expected Output: 366
Explanation: Spanning through leap year 2024 gives 366 days.
Hints
- Convert each date to a single integer 'day count' from a fixed anchor (e.g. days since 1900-01-01), then the answer is the absolute difference of the two counts.
- To count days into a year, sum days_in_month for all months before the given month, then add the day-of-month. Sum whole-year lengths (365 or 366) for the years before the given year.
- A year is a leap year if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0. Test 1900 (not leap), 2000 (leap), 2024 (leap).
- Since the dates may be in either order, take abs() of the difference so the result is always non-negative.