Обратный отсчет Momentjs - Продолжительность показывает отрицательные числа

Я пытаюсь создать обратный отсчет с помощью MomentJS (2.22.2) и Rxjs (6.2.2) interval. Но когда я достигаю некоторых моментов времени, мой обратный отсчет сходит с ума и выводит отрицательные числа, где он должен был, например, вычесть день и начаться в 23 часа.

Любая помощь в том, как мне это исправить?


Пример

местное время: 2018-09-05T18:49

Конец: 2018-11-03T18:00

это приводит к:

Обратный отсчет Momentjs - Продолжительность показывает отрицательные числа


Мой код

'this.days', 'this.hours', 'this.minutes' и 'this.seconds' - это локальные переменные, которые содержат строковое представление результирующего времени (строковый формат, потому что я хочу показать ведущие нули)

interval(1000).subscribe(() => {
      const now = moment();
      let timeLeft = this.endDate.diff(now, 'milliseconds', true);
      let endDate = moment(this.endDate); // Use 'moment' to make a new copy

      // Days
      const days = Math.floor(moment.duration(timeLeft).asDays());
      console.warn(moment.duration(timeLeft).asDays());
      this.days = Countdown.addLeadingZeros(days.toString(), 3);

      endDate = endDate.subtract(days, 'days');
      timeLeft = endDate.diff(now, 'milliseconds', true);

      // Hours
      const hours = Math.floor(moment.duration(timeLeft).asHours());
      console.warn(Math.round(moment.duration(timeLeft).asHours()));
      this.hours = Countdown.addLeadingZeros(hours.toString(), 2);

      endDate = endDate.subtract(hours, 'hours');
      timeLeft = endDate.diff(now, 'milliseconds', true);

      // Minutes
      const minutes = Math.floor(moment.duration(timeLeft).asMinutes());
      this.minutes = Countdown.addLeadingZeros(minutes.toString(), 2);

      endDate = endDate.subtract(minutes, 'minutes');
      timeLeft = endDate.diff(now, 'milliseconds', true);

      // Seconds
      const seconds = Math.floor(moment.duration(timeLeft).asSeconds());
      this.seconds = Countdown.addLeadingZeros(seconds.toString(), 2);
});

Кто-нибудь видит, что я здесь делаю не так или как я могу улучшить этот код?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
1 473
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Отрицательные числа возникают в вашем коде из-за перехода на летнее время.

Здесь, в Великобритании, есть переход на летнее время с 2018-09-05 на 2018-11-03. Фактически он находится на 2018-10-28. Я могу воспроизвести вашу проблему, если выберу две даты по обе стороны от нее, но не если обе даты находятся на одной стороне. Я предполагаю, что там, где вы живете, также есть переход на летнее время между 2018-09-05 и 2018-11-03.

Самый простой способ избежать подобных проблем - рассчитать разницу во времени, используя время в формате UTC. Вместо того, чтобы писать

  const now = moment();

написать

  const now = moment().utc();

и убедитесь, что this.endDate создан в UTC, а не по местному времени.

В этих датах действительно установлено летнее время (маби, больше нет! independent.co.uk/news/world/europe/…) В любом случае, как бы вы «оживили» дату в формате utc? moment.utc().toISODate() дает мне: 2018-09-05T22:45:00.890Z. Но когда я использую moment(<date>) или moment().utc(<date>), я получаю предупреждение об устаревании.

Mr.wiseguy 05.09.2018 22:45

@ Mr.wiseguy: Для меня moment("2018-09-05T22:45").utc().format() печатает 2018-09-05T21:45:00Z. Я не могу воспроизвести предупреждение об устаревании: можно ли перечислить точные строки, которые вы используете при записи <date>? Также непонятно, что вы имеете в виду под словом «возродить» - не могли бы вы объяснить больше?

Luke Woodward 06.09.2018 21:00

Я делал moment().utc().toISODate() и восстанавливал строку через moment(<iso-string>).utc(), где я должен был сделать moment().utc().format() для строки и moment(<date>).utc() для текущей даты. Теперь это работает. Большое спасибо!

Mr.wiseguy 10.09.2018 22:43

Другие вопросы по теме