Как рассчитать округленные месяцы и дни до целевой даты, игнорируя часовые пояса и летнее время? - PullRequest
0 голосов
/ 04 октября 2018

Я хочу создать таймер, который отображает округленные месяцы и дни, оставшиеся до локальной целевой даты, игнорируя часовые пояса и переход на летнее время.

Чтобы уточнить, с целевой датой 2018-12-10:

При 2018-10-08 23:01 это должно привести к 2 months 2 days
При 2018-10-09 00:01 это должно привести к 2 months 1 days
При 2018-10-09 02:01 это должно привести к 2 months 1 days
При 2018-12-09 23:59 это должнорезультат в 0 months 1 days

Как видно, дни всегда должны начинаться и заканчиваться в 00:00 по местному времени, независимо от того, является ли целевая дата после изменения летнего времени в местном часовом поясе или нет.

При наивном подходе изменение DST отбрасывает его, и оно также не учитывает неполных дней:

const target = moment('2018-12-10')

const t1 = moment('2018-10-08 23:01')
const t2 = moment('2018-10-09 00:01')
const t3 = moment('2018-10-09 02:01')
const t4 = moment('2018-12-09 23:59')

const d1 = moment.duration(target.diff(t1))
const d2 = moment.duration(target.diff(t2))
const d3 = moment.duration(target.diff(t3))
const d4 = moment.duration(target.diff(t4))

// render() ...
{d1.months()} months {d1.days()} days
{d2.months()} months {d2.days()} days
{d3.months()} months {d3.days()} days
{d4.months()} months {d4.days()} days

приводит к:

2 months 1 days
2 months 1 days
2 months 0 days
0 months 0 days

Что было бы правильнымподход к расчету дней без влияния изменений летнего времени в течение продолжительности?

1 Ответ

0 голосов
/ 04 октября 2018

Вы можете использовать startOf () , чтобы сначала округлить дату вниз.

Так что если вы сделаете что-то вроде этого:

const target = moment('2018-12-10')

const t1 = moment('2018-10-08 23:01').startOf('day');
const t2 = moment('2018-10-09 00:01').startOf('day');
const t3 = moment('2018-12-09 23:59').startOf('day');

const d1 = moment.duration(target.diff(t1))
const d2 = moment.duration(target.diff(t2))
const d3 = moment.duration(target.diff(t3))

console.log(d1.months() + " months " + d1.days() + " days");
console.log(d2.months() + " months " + d2.days() + " days");
console.log(d3.months() + " months " + d3.days() + " days");

Результат будет:

2 months 2 days
2 months 1 days
0 months 1 days

Вы также можете использовать isDST () , чтобы вычислить, наблюдается ли DST.Если это так, вы бы сначала вычли час.Использование может выглядеть примерно так:

let t1 = moment('2018-10-08 00:01');
t1 = t1.isDST() ? t1.subtract(1, 'hours').startOf('day') : t1.startOf('day');
...