最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Compare two UTC dates with date-fns - Stack Overflow

programmeradmin2浏览0评论

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
  • Does one value have non-zero milliseconds? Log .toISOString() on the dates to check. – Matt Johnson-Pint Commented Jun 10, 2020 at 19:53
  • 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()}`); – Leonardo Freua Commented Jun 10, 2020 at 20:04
Add a comment  | 

2 Answers 2

Reset to default 10

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.

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.

发布评论

评论列表(0)

  1. 暂无评论