Compare two UTC dates with date-fns
Asked Answered
G

2

9

I'm trying to compare two dates in UTC format with date-fns, but I'm not getting it. The two values ​​look the same, but the isEquals() function returns false for comparison.

The purpose of the code below is to search for the schedules that are marked and check if they fit the times of the array range, if there is a compatible schedule, it returns the object by inserting it in the constant date

import React, { useState, useEffect } from 'react';
import { utcToZonedTime } from 'date-fns-tz';
import {
  format,
  setHours,
  setMinutes,
  setSeconds,
  isBefore,
  isEqual,
  parseISO,
} from 'date-fns';
import enUS from 'date-fns/locale/en-US';

import api from '~/services/api';

const range = [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];

export default function Dashboard() {
  const [date, setDate] = useState(new Date());

  useEffect(() => {
    async function loadSchedule() {
      const response = await api.get('schedule', {
        params: { date },
      });

      const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;

      const data = range.map((hour) => {
        const checkDate = setSeconds(setMinutes(setHours(date, hour), 0), 0);
        const compareDate = utcToZonedTime(checkDate, timezone);

        return {
          time: `${hour}:00h`,
          past: isBefore(compareDate, new Date()),
          appointment: response.data.find((appoint) =>
            isEqual(parseISO(appoint.date), compareDate)
          ),
        };
      });

      setSchedule(data);
    }

    loadSchedule();
  }, [date]);

}

I made a test code to print the results on the Reactotron and below are the printed values:

console.tron.log(`${isEqual(parseISO(response.data[1].date), 
                   compareDate)}\n
                   ${parseISO(response.data[1].date)}\n${compareDate}`);

Result:

false
Wed Jun 10 2020 19:00:00 GMT-0300 (Brasilia Standard Time)
Wed Jun 10 2020 19:00:00 GMT-0300 (Brasilia Standard Time)

Actual values ​​for each of the dates:

console.tron.log(`${response.data[1].date}\n${compareDate}`);
2020-06-10T22:00:00.000Z
Wed Jun 10 2020 20:00:00 GMT-0300 (Brasilia Standard Time)

But if I print only the value of the compareDate variable, it changes the format:

console.tron.log(compareDate);
2020-06-10T21:00:00.002Z
Gangboard answered 10/6, 2020 at 19:39 Comment(2)
Does one value have non-zero milliseconds? Log .toISOString() on the dates to check.Changeable
I am using the partner because of the time zone. I tried using .toISOString (), but the following error occurred: Unhandled Rejection (TypeError): response.data[1].date.toISOString is not a function The test wen like this: console.tron.log(${parseISO(response.data[1].date)}\n${response.data[1].date.toISOString()}`);Gangboard
S
9

date-fns's isEqual() function also takes into consideration the milliseconds value, as questioned in the comments.

This information can also be found on date-fns isEqual() docs, in the example:

// Are 2 July 2014 06:30:45.000 and 2 July 2014 06:30:45.500 equal?

var result = isEqual(
  new Date(2014, 6, 2, 6, 30, 45, 0),
  new Date(2014, 6, 2, 6, 30, 45, 500)
)
// it returns false`

You should import setMilliseconds() from date-fns and also use it in the line where you set checkDate value.

Scow answered 14/7, 2020 at 2:10 Comment(0)
S
0

You can compare two dates without using date-fns like this:

const areDatesEqual = (d1, d2) => {
  return new Date(d1).valueOf() === new Date(d2).valueOf();
}

console.log(areDatesEqual(Date(), Date())); // true
console.log(areDatesEqual(new Date('01/01/2020'), new Date('01/01/2020'))); // true
console.log(areDatesEqual(new Date('01/01/2020'), new Date('01/02/2020'))); // false

This approach works with both date objects and date strings. You might need to add extra validation for the d1 and d2 arguments, but this should give you a good starting point.

Generally, you can compare dates using relational operators like < and >. However, using === for date objects won't work as expected because it checks for reference equality rather than value equality.

Sturm answered 9/9, 2024 at 19:38 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.