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
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
Share
Improve this question
edited Jun 10, 2020 at 20:17
Leonardo Freua
asked Jun 10, 2020 at 19:39
Leonardo FreuaLeonardo Freua
3211 gold badge2 silver badges12 bronze badges
2
|
2 Answers
Reset to default 10date-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.
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.
.toISOString()
on the dates to check. – Matt Johnson-Pint Commented Jun 10, 2020 at 19:53console.tron.log(${parseISO(response.data[1].date)}\n${response.data[1].date.toISOString()}`);
– Leonardo Freua Commented Jun 10, 2020 at 20:04