A checklist of the date problems people hit most, with fixes.
1. Months are zero-based
console.log(new Date(2026, 0, 1).getMonth()); // → 0 (January)
console.log(new Date(2026, 11, 31).getMonth()); // → 11 (December)
Fix: remember to add or subtract 1 when you show or read the month.
2. “2026-03-15” shows as the 14th
Date-only strings are UTC, and your zone may be behind it. Fix: format with timeZone: "UTC", or build the date with local parts: new Date(2026, 2, 15).
3. Invalid dates do not throw
function parseDate(text) {
const d = new Date(text);
return Number.isNaN(d.getTime()) ? null : d;
}
console.log(parseDate("2026-03-15")?.toISOString()); // → 2026-03-15T00:00:00.000Z
console.log(parseDate("hello")); // → null
Always check with Number.isNaN(date.getTime()) when the input comes from a user.
4. Comparing with ===
console.log(new Date(0) === new Date(0)); // → false
console.log(new Date(0).getTime() === new Date(0).getTime()); // → true
5. Same day, different time
To compare days, compare the date part only.
function sameDay(a, b) {
return a.toISOString().slice(0, 10) === b.toISOString().slice(0, 10);
}
console.log(sameDay(new Date("2026-03-15T01:00:00Z"), new Date("2026-03-15T23:00:00Z"))); // → true
(This compares UTC days. For local days, compare getFullYear(), getMonth() and getDate().)
6. Date inputs give strings
<input type="date"> returns "YYYY-MM-DD", a string. Treat it as a date-only value.
<input type="date" id="d" value="2026-03-15">
<p id="out"></p>
<script>
const input = document.querySelector("#d");
const out = document.querySelector("#out");
function update() {
const [y, m, d] = input.value.split("-").map(Number);
const date = new Date(y, m - 1, d); // local date, no zone surprises
out.textContent = date.toLocaleDateString(undefined, { dateStyle: "full" });
}
input.addEventListener("input", update);
update();
</script>
7. Two-digit years and odd formats
new Date("3/4/26") is ambiguous and differs between browsers. Prefer ISO strings and parse other formats yourself.
8. When Date is not enough
For heavy date work (recurring events, calendar maths, many zones) use a well-tested library, or the newer built-in Temporal API once it is supported where you need it. Check browser support first, and do not rely on proposals that have not shipped.
Be honest about complexity
Intl for display, and test the edge cases.