Blog

Comparing Two Dates in JavaScript Without the Time Zone Gotchas

Date comparisons trip up almost every JavaScript developer at some point. Two Date objects can look the same in the console and still fail a strict equality check, because equality compares the underlying timestamp down to the millisecond.

The fix is usually one of two approaches: build a string from the date parts, or use the built-in toDateString method. Both ignore the time of day, which is usually what you want when comparing, say, two birthdays or a deadline to today.

What happened:

  • GetDate returns the day of the month based on local time.
  • GetMonth returns the month, indexed from 0.
  • GetFullYear returns the four-digit year.
  • ToDateString returns a formatted date string like "Mon Dec 16 2019".
  • None of these approaches compare the time portion.

Approach 1: build a string from date parts

The simplest version pulls the day, month, and year out of each Date object, glues them together with a delimiter, and compares the strings. If you do not want to think about locale, use a delimiter that does not appear in the data, like a hyphen or a pipe.

Here is the pattern: take a helper that accepts any two Date objects, format each one as a hyphen-separated string pulled from the date parts, and return the result of comparing those two formatted strings.

“`javascript

Function areSameDay(a, b) {

Const left = `${a.getDate()}-${a.getMonth()}-${a.getFullYear()}`;

Const right = `${b.getDate()}-${b.getMonth()}-${b.getFullYear()}`;

Return left === right;

}

Console.log(areSameDay(new Date(), new Date())); // true

“`

Two things to watch. GetMonth returns 0 for January, not 1. If you build the string manually, add 1 to that value, or at least remember it when you read the output. The other thing: this returns true only on the same calendar day in the same local time zone.

Approach 2: use toDateString

The other route leans on the language. ToDateString returns a human-readable string in English, in the form "Mon Dec 16 2019". Two dates that fall on the same calendar day return the same string in the same locale.

“`javascript

Const a = new Date();

Const b = new Date();

Console.log(a.toDateString() === b.toDateString()); // true

“`

That is the whole snippet. Less to type, easier to read. The downside is that the format is fixed and English-only by default, so do not try to parse it back into a Date.

Pick the right approach

Goal Best pick Why
Quick same-day check toDateString One line, no formatter to maintain
Custom output format Manual getDate/getMonth/getFullYear You control the layout
Need to include time getTime or getHours/getMinutes/getSeconds Time-aware comparisons require timestamp math
Multiple locales or zones date-fns or Day.js Both handle i18n and offsets

If you only care whether two dates fall on the same day, either approach works. ToDateString is shorter and reads better. The custom string is better if you want to choose the format yourself or build it into a larger string like "2024-03-15".

If you need to compare the time of day, neither approach is enough. You will have to compare getHours, getMinutes, and getSeconds separately, or compare the timestamps with getTime.

Say you are checking a subscription expiry

Say you are building a small app that shows "your trial ends today" only on the day the trial ends, not the day after. Pull today's date and the expiry date from your data store, compare them with toDateString, and flag the banner only when the strings match. That single check is what stops the "ends today" message from appearing on day two of a paid plan.

Our analysis

These two approaches feel complete, but they share a quiet limit. They only work in the local time zone of the machine running the script. Move your code to a server in another region and the same comparison can shift by a day. For anything user-facing, that drift turns into bug reports within a week.

The trade-off is real. The hand-rolled methods are zero dependencies and zero kilobytes, which matters on a lightweight landing page. A library like date-fns or Day.js costs about the size of a small image but gives you proper UTC handling, parsing, and formatting out of the box. Read the request before reaching for either.

Who benefits most from the lightweight approach? Solo developers shipping a static site, students writing interview prep, anyone maintaining a small script. Who loses out? Teams shipping anything cross-region, anything that touches a database timestamp, anything that has to survive daylight saving changes without surprise.

What to watch next

If you are doing anything more serious than same-day comparisons, look into a real date library. Date-fns and Day.js are both small, modern, and handle time zones properly. The hand-rolled approach above is fine for quick checks but does not scale to recurring events, calendars, or anything with a server in a different time zone.

Key takeaways

  • Use toDateString for one-line day equality checks.
  • Build a string from getDate, getMonth, getFullYear when you need a custom format.
  • Neither approach compares the time of day.

Frequently asked questions

Why does new Date() === new Date() return false?

Because strict equality compares the timestamp inside each Date object, down to the millisecond. Two Date objects created one millisecond apart will not be equal.

Does getMonth return 1 for January?

No. JavaScript months are zero-indexed, so January is 0 and December is 11.

Will comparing dates with toDateString work across time zones?

Not safely. ToDateString uses the local time zone of the machine running the code. For cross-zone comparisons, normalize to UTC or use a date library.

Can I include the time with these approaches?

No. These methods ignore the time portion of the Date. For time-aware comparisons, use getTime, getHours, or a full date library.

Is there a built-in JavaScript function that just compares two dates?

No. JavaScript has no Date.compare method. You have to write the comparison logic yourself, or pull in a library.

Related