Problem

Given a start date start, an end date end, and a positive integer step, return a generator object that yields dates in the range from start to end inclusive.

The value of step indicates the number of days between consecutive yielded values.

All yielded dates must be in the string format YYYY-MM-DD.

Examples

Example 1: Input: start = “2023-04-01”, end = “2023-04-04”, step = 1 Output: [“2023-04-01”,“2023-04-02”,“2023-04-03”,“2023-04-04”]

Example 2: Input: start = “2023-04-10”, end = “2023-04-20”, step = 3 Output: [“2023-04-10”,“2023-04-13”,“2023-04-16”,“2023-04-19”]

Example 3: Input: start = “2023-04-10”, end = “2023-04-10”, step = 1 Output: [“2023-04-10”]

Constraints:

  • new Date(start) <= new Date(end)
  • start and end dates are in the string format YYYY-MM-DD
  • 0 <= The difference in days between the start date and the end date <= 1500
  • 1 <= step <= 1000

Solution

Method 1 – Date Increment Generator 1

Intuition

We can generate the required date range by starting from the start date and incrementing by step days each time, yielding each date until we pass the end date. This works because date arithmetic is well-defined and the constraints are small.

Approach

  1. Parse the start and end strings into date objects.
  2. Use a loop to yield the current date in YYYY-MM-DD format.
  3. Increment the current date by step days each iteration.
  4. Stop when the current date exceeds the end date.
  5. Handle edge cases where start == end or step is large.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function* dateRangeGenerator(start, end, step) {
    let curr = new Date(start);
    let last = new Date(end);
    while (curr <= last) {
        let y = curr.getFullYear();
        let m = (curr.getMonth() + 1).toString().padStart(2, '0');
        let d = curr.getDate().toString().padStart(2, '0');
        yield `${y}-${m}-${d}`;
        curr.setDate(curr.getDate() + step);
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function* dateRangeGenerator(start: string, end: string, step: number): Generator<string> {
    let curr = new Date(start);
    let last = new Date(end);
    while (curr <= last) {
        let y = curr.getFullYear();
        let m = (curr.getMonth() + 1).toString().padStart(2, '0');
        let d = curr.getDate().toString().padStart(2, '0');
        yield `${y}-${m}-${d}`;
        curr.setDate(curr.getDate() + step);
    }
}

Complexity

  • ⏰ Time complexity: O(n) where n is the number of yielded dates, because we increment and yield once per output date.
  • 🧺 Space complexity: O(1), as only a few variables are used regardless of the range size.