momentjs неправильно вычисляет разницу в датах - PullRequest
0 голосов
/ 01 ноября 2018

В моем угловом веб-приложении я хочу сравнить две даты, чтобы увидеть, не достиг ли человека возраста 18 лет, когда он / она вошел в компанию. Вот код, который я использую для этого:

  const dayOfBirth = moment(formControl.value, this.dateFormat, true).startOf('day');
  const entranceDateControl = this.wizardFormGroup.get('entranceDate');
  const entranceDate = moment(entranceDateControl.value, this.dateFormat, true).startOf('day');

  // Check validation rule R3: Age is less than 18 compared to entrance date
  const difference = moment.duration(Math.abs(entranceDate.diff(dayOfBirth)));
  if (difference.years() < 18) {
    const validationMessage = this.getValidationMessage('R3', formControlName);
    return validationMessage ? validationMessage.message : null;
  }

Как видите, я использую startOf('day'), чтобы избавиться от любого компонента времени, чтобы я обрабатывал только даты. Я использую diff(), чтобы получить разницу между двумя датами, а затем duration(), чтобы преобразовать разницу в годы, месяцы, дни и т. Д. Используя этот код, сообщение проверки не должно отображаться, когда человеку исполняется 18 лет. день, когда она / он вошел в компанию.

После тестирования я натолкнулся на странное, на мой взгляд, поведение. В зависимости от месяца и года, это дало разные результаты. Например, на эти даты все было в порядке:

dayOfBirth   = 1998-03-01, 1998-04-01, ..., 2000-02-01
entranceDate = 2016-03-01, 2016-04-01, ..., 2018-02-01

Но следующие даты вернули сообщение проверки:

dayOfBirth   = 2000-03-01, 2000-04-01, ..., 2002-02-01
entranceDate = 2018-03-01, 2000-04-01, ..., 2020-02-01

После этих дат, то есть, используя 2002-03-01 и далее, он снова работает. Я также получил неправильный результат за даты, предшествующие 1998-03-01.

Теперь я более внимательно посмотрел на объект Duration и заметил, что для времен менее 18 лет он вычислял 864 миллисекунды меньше , чем когда пришел к правильному выводу, что между датами было 18 лет.

Correct duration
----------------
dayOfBirth   = 1998-03-01, 1998-04-01, ..., 2000-02-01
entranceDate = 2016-03-01, 2016-04-01, ..., 2018-02-01

Duration = 568080000000 ms

Wrong duration
--------------
dayOfBirth   = 2000-03-01, 2000-04-01, ..., 2002-02-01
entranceDate = 2018-03-01, 2000-04-01, ..., 2020-02-01

Duration = 567993600000 ms

Duration difference
-------------------
568080000000 - 567993600000 = 86400000 ms = 24 hours = 1 day

Кто-нибудь объяснил это? Можно ли это считать ошибкой в ​​моментах? Любой жизнеспособный обходной путь для этого?

1 Ответ

0 голосов
/ 01 ноября 2018

Я не вдавался в детали в исходном коде, но кажется, duration() подшучивает над вами. Упростите код и полагайтесь только на diff, как указано ниже, и вы должны быть хороши (по крайней мере, это работает для предоставленных вами примеров). И это легче на глазах:)

const moment = require('moment')

const dayOfBirth = moment('2000-03-01').startOf('day');
const entranceDate = moment('2018-03-01').startOf('day');
const difference = entranceDate.diff(dayOfBirth, 'years') 

if (difference < 18) {
  console.log( '<18')
} else {
  console.log( '>=18')
}

выдаст >=18

...