Я пытаюсь создать обратный отсчет с помощью MomentJS (2.22.2
) и Rxjs (6.2.2
) interval
. Но когда я достигаю некоторых моментов времени, мой обратный отсчет сходит с ума и выводит отрицательные числа, где он должен был, например, вычесть день и начаться в 23 часа.
Любая помощь в том, как мне это исправить?
Пример
местное время: 2018-09-05T18:49
Конец: 2018-11-03T18:00
это приводит к:
Мой код
'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);
});
Кто-нибудь видит, что я здесь делаю не так или как я могу улучшить этот код?
Отрицательные числа возникают в вашем коде из-за перехода на летнее время.
Здесь, в Великобритании, есть переход на летнее время с 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, а не по местному времени.
@ Mr.wiseguy: Для меня moment("2018-09-05T22:45").utc().format()
печатает 2018-09-05T21:45:00Z
. Я не могу воспроизвести предупреждение об устаревании: можно ли перечислить точные строки, которые вы используете при записи <date>
? Также непонятно, что вы имеете в виду под словом «возродить» - не могли бы вы объяснить больше?
Я делал moment().utc().toISODate()
и восстанавливал строку через moment(<iso-string>).utc()
, где я должен был сделать moment().utc().format()
для строки и moment(<date>).utc()
для текущей даты. Теперь это работает. Большое спасибо!
В этих датах действительно установлено летнее время (маби, больше нет! independent.co.uk/news/world/europe/…) В любом случае, как бы вы «оживили» дату в формате utc?
moment.utc().toISODate()
дает мне:2018-09-05T22:45:00.890Z
. Но когда я используюmoment(<date>)
илиmoment().utc(<date>)
, я получаю предупреждение об устаревании.