Get All Dates Between Two Dates in JavaScript
To list every day between two dates, iterate a Temporal.PlainDate with .add({ days: 1 }) until you reach the end β calendar-day steps that never drift across DST. Part of Working with Date Ranges and Intervals.
Why this scenario is tricky
Enumerating the days between two dates by adding 24 hours in a loop drifts across a DST transition: on the spring-forward day, 24 hours lands you at 01:00 the next day instead of 00:00, and after enough iterations you skip or repeat a date. The fix is to iterate on a calendar type β Temporal.PlainDate β where .add({ days: 1 }) means the next calendar day regardless of how many real hours it contained.
Minimal working solution
Loop while the cursor is before the end, collecting each PlainDate.
import { Temporal } from '@js-temporal/polyfill';
function datesBetween(start: Temporal.PlainDate, end: Temporal.PlainDate) {
const out: Temporal.PlainDate[] = [];
// Half-open: include start, exclude end.
for (let d = start; Temporal.PlainDate.compare(d, end) < 0; d = d.add({ days: 1 })) out.push(d);
return out;
}
Full production version
A generator avoids allocating the whole array for long ranges, and a step parameter supports every-N-days.
import { Temporal } from '@js-temporal/polyfill';
function* eachDate(start: Temporal.PlainDate, end: Temporal.PlainDate, step = 1) {
if (step < 1) throw new RangeError('step must be >= 1');
for (let d = start; Temporal.PlainDate.compare(d, end) < 0; d = d.add({ days: step })) yield d;
}
// for (const d of eachDate(a, b)) render(d);
Verification snippet
Common pitfalls
Frequently Asked Questions
How do I list every date between two dates without DST bugs?
Iterate on Temporal.PlainDate and advance with .add({ days: 1 }). Because PlainDate has no time or zone, each step is exactly one calendar day, so a range crossing a daylight-saving boundary produces the correct list with no skipped or duplicated dates.
Should the end date be included in the list?
Follow the half-open convention and exclude it: loop while compare(cursor, end) < 0. That way a range from Monday to Thursday yields Monday, Tuesday, Wednesday, and two adjacent ranges never share a date.