Skip to content

如何在JavaScript中计算日期差异

处理日期是困难的,但通常是必要的,这也是为什么有这么多与日期相关的库存在的原因。然而,一些任务,比如计算两个日期之间的差异,可以很容易地用原生JavaScript来完成。

[!NOTE]

你可能不熟悉JavaScript的数字分隔符,它们在下面的示例中使用。它们是使大型数字值更易读的语法糖

以秒为单位的日期差异

计算以秒为单位的日期差异就像是将两个Date对象相减,然后除以一秒钟的毫秒数(1000)。

const dateDifferenceInSeconds = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / 1_000;

dateDifferenceInSeconds(
  new Date('2020-12-24 00:00:15'),
  new Date('2020-12-24 00:00:17')
); // 2

以分钟为单位的日期差异

类似地,要计算以分钟为单位的日期差异,我们只需要将除数更改为一分钟的毫秒数(1000 * 60)。

const dateDifferenceInMinutes = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / 60_000;

```js
const dateDifferenceInWeekdays = (dateInitial, dateFinal) => {
  const oneDay = 24 * 60 * 60 * 1000; // milliseconds in a day
  const startDate = new Date(dateInitial);
  const endDate = new Date(dateFinal);

  // Calculate the difference in days
  const diffDays = Math.round(Math.abs((startDate - endDate) / oneDay));

  // Calculate the number of weekends
  let weekends = 0;
  for (let i = 0; i <= diffDays; i++) {
    const currentDate = new Date(startDate.getTime() + i * oneDay);
    if (currentDate.getDay() === 0 || currentDate.getDay() === 6) {
      weekends++;
    }
  }

  // Calculate the number of weekdays
  const weekdays = diffDays - weekends;

  return weekdays;
};

dateDifferenceInWeekdays(
  new Date('2021-04-19'),
  new Date('2021-04-26')
); // 5

This function calculates the difference in weekdays between two dates. It first calculates the difference in days using the same method as before. Then, it iterates over each day in the range and checks if it's a weekend day (Saturday or Sunday). If it is, it increments the weekends counter. Finally, it subtracts the number of weekends from the total difference in days to get the number of weekdays.

计算工作日之间的日期差异稍微复杂一些。我们首先需要确定一个给定日期是否是工作日。然后,我们需要创建一个包含两个日期之间的所有日期的数组,并过滤掉周末。这可以使用Array.from()和一个将天数添加到日期的函数来完成。最后,我们可以使用Array.prototype.filter()来过滤掉周末,并返回结果数组的长度。

const isWeekday = date => date.getDay() % 6 !== 0;
const addDaysToDate = (date, n) => {
  const d = new Date(date);
  d.setDate(d.getDate() + n);
  return d;
};

const dateDifferenceInWeekdays = (startDate, endDate) =>
  Array
    .from({ length: (endDate - startDate) / 86_400_000 })
    .filter((_, i) => isWeekday(addDays(startDate, i + 1)))
    .length;

dateDifferenceInWeekdays(
  new Date('Oct 05, 2020'),
  new Date('Oct 06, 2020')
); // 1
dateDifferenceInWeekdays(
  new Date('Oct 05, 2020'),
  new Date('Oct 14, 2020')
); // 7

[!WARNING]

上面的代码片段可能不适用于实际情况,因为它没有考虑官方假期。如果您打算在生产环境中使用它,建议调整工作日检查以包括已知假期的列表。

周差异

计算周差异仍然可以通过简单的日期相减来实现。我们只需要将毫秒差异除以一周的毫秒数(1000 * 60 * 60 * 24 * 7)。

const dateDifferenceInWeeks = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / 604_800_000;

dateDifferenceInWeeks(
  new Date('2023-01-01'),
  new Date('2023-01-08')
); // 1

月差异

使用其他Date方法来计算月份和年份比使用减法更容易。在这种情况下,我们更喜欢使用Date.prototype.getFullYear()Date.prototype.getMonth()来计算两个日期之间的差异。

const dateDifferenceInMonths = (dateInitial, dateFinal) =>
  Math.max(
    (dateFinal.getFullYear() - dateInitial.getFullYear()) * 12 +
      dateFinal.getMonth() -
      dateInitial.getMonth(),
    0
  );

dateDifferenceInMonths(
  new Date('2017-12-13'),
  new Date('2018-04-29')
); // 4

年份差异

计算年份差异与前面的例子类似,但我们只需要将月份差异除以12

const dateDifferenceInYears = (dateInitial, dateFinal) =>
  dateDifferenceInMonths(dateInitial, dateFinal) / 12;

dateDifferenceInYears(
  new Date('2017-12-13'),
  new Date('2019-12-15')
); // 2