How to compare two dates correctly in JavaScript

Oct 15, 2023#javascript#how-to

Checking if a date falls between two specific dates in JavaScript is a fundamental requirement for applications that involve date-based validation, event filtering, or date range selection, ensuring that data or events are within the desired timeframe.



When comparing dates in JavaScript, common mistakes include neglecting timezones and precision, not normalizing dates, ignoring the time component, using loose equality operators, assuming object equality, and not handling edge cases like daylight saving time changes.

Prerequisites

A Date object is a built-in object in JavaScript that stores the date and time. It provides a number of built-in methods for formatting and managing that data. Date objects are often interpreted in the local timezone by default. Be cautious when working with dates in different timezones to avoid unexpected behavior.

A Date object has an underlying timestamp, which is an integer number representing the number of milliseconds that has passed since the beginning of 1970. This timestamp is also known as the Unix epoch, which is the standard reference point for measuring time across different systems. This timestamp is timezone-agnostic and uniquely defines an instant in history.

The use of timestamps for date comparisons is now common in various programming languages and systems beyond just Unix and JavaScript. It offers a standardized and efficient way to work with dates and times.

Comparison operators, such as <, >, <=, and >=, compare the numeric values of the operands. If the operands are not numbers, they are converted to numbers before the comparison. However, if you compare an object to a primitive value, the object is not converted to a primitive value.

Equality operators, such as ==, !=, ===, and !==, test if two values are equal or not. The difference between them is that == performs type conversion if the operands are of different types, while === does not.

When comparing dates, it’s typically the values that you care about, not the references to the Date objects themselves.

Comparing two Date objects

When you use comparison operators with Date objects, JavaScript converts the objects to numeric values (timestamps) and then performs the comparison. This is because these operators are defined to work with numeric values, not objects. Therefore, you are effectively comparing the timestamps when using comparison operators.

let date1 = new Date("2023-10-15T12:00:00Z");
let date2 = new Date("2022-11-10T12:00:00Z");

if (date1 > date2) {
  console.log("Date 1 is greater than date 2");
} else if (date1 < date2) {
  console.log("Date 1 is less than date 2");
} else {
  console.log("Both dates are same");
}

// Output:
// Date 1 is greater than date 2

However when you use equality operators, which compare the object references themselves, not the contents or values of the objects. In other words, they check if two objects are the same instance in memory. When you compare Date objects using equality operators, you are checking if both objects reference the exact same Date instance in memory.

const date1 = new Date('2023-10-15T12:00:00Z');
const date2 = new Date('2023-10-15T12:00:00Z');
const date3 = date1; // Assigning the same Date object to date3

console.log(date1 == date2);  // false (different instances)
console.log(date1 != date2);  // true (different instances)
console.log(date1 === date2); // false (different instances)
console.log(date1 !== date2); // true (different instances)

console.log(date1 == date3);  // true (same instance)
console.log(date1 != date3);  // false (same instance)
console.log(date1 === date3); // true (same instance)
console.log(date1 !== date3); // false (same instance)

This difference in behavior is rooted in JavaScript’s operator overloading and its dynamic typing system. Comparison operators are designed to work with various types, and JavaScript implicitly converts objects to their primitive values (timestamps in the case of Date objects) when necessary. On the other hand, equality operators explicitly compare object references.

Comparing a Date object to a timestamp

When you compare a Date object to a timestamp using comparison operators, JavaScript will implicitly convert the Date object to its timestamp equivalent before performing the comparison.

const date = new Date('2023-10-15T12:00:00Z');
const timestamp = Date.parse('2023-10-15T12:00:00Z');

if (date < timestamp) {
  console.log('The date is earlier than the timestamp.');
} else if (date > timestamp) {
  console.log('The date is later than the timestamp.');
} else {
  console.log('The date and the timestamp are the same.');
}

// Output:
// The date and the timestamp are the same.

When you compare a Date object to a timestamp using equality operators, JavaScript will not implicitly convert the Date object to its timestamp equivalent. Instead, it will compare the Date object directly with the numeric value.

const date = new Date('2023-10-15T12:00:00Z');
const timestamp = Date.parse('2023-10-15T12:00:00Z');

console.log(date.getTime()); // 1697371200000
console.log(timestamp);      // 1697371200000
console.log(date.getTime() == timestamp); // true

console.log(date == timestamp);  // false
console.log(date != timestamp);  // true
console.log(date === timestamp); // false
console.log(date !== timestamp); // true

Comparing two timestamps

You can obtain a timestamp using various methods and properties associated with the Date object: Date.now(), Date.parse(), getTime() or valueOf().

Both methods getTime() and valueOf() return the same timestamp and can be used interchangeably to compare using any operator. This is equivalent to comparing the Date objects directly, but it allows you to use the equality operators ==, !=, ===, and !== as well.

let date1 = new Date("2023-10-15T12:00:00Z");
let date2 = new Date("2022-10-10T12:00:00Z");

if (date1.getTime() == date2.getTime()) {
  console.log("Both Dates are same");
} else if (date1.getTime() > date2.getTime()) {
  console.log("Date 1 is greater than Date 2");
} else {
  console.log("Date 1 is less than Date 2");
}

// Output:
// Date 1 is greater than Date 2

Comparing specific parts of date

You can use the getDate(), getMonth(), getFullYear(), and other similar methods to get the specific parts of a date, such as the day, month, year, hour, minute, etc., and then compare them individually or in combination. This allows you to perform more granular comparisons, such as checking if two dates are in the same month or year.

let date1 = new Date("2023-10-15T12:00:00Z");
let date2 = new Date("2022-10-10T12:00:00Z");

if (date1.getMonth() == date2.getMonth()) {
  console.log("Both dates are in the same month");
} else if (date1.getMonth() > date2.getMonth()) {
  console.log("Date 1 is in a later month than Date 2");
} else {
  console.log("Date 1 is in an earlier month than Date 2");
}

// Output:
// Both dates are in the same month