Как мне преобразовать эту дату из моментов в простой JavaScript - PullRequest
0 голосов
/ 28 декабря 2018

У меня есть метка времени, которую я пытаюсь округлить до ближайшего UTC понедельника 00: 00: 00: 00: 000Z

Мой код в данный момент выглядит так

let now = Date.now()
moment.unix(now / 1000).utc().startOf("isoWeek").valueOf()

Япытаюсь сделать это простым JS без мгновений, и я не получаю тот же ответ

const nearestMonday = date => {
    const monday     = 1;
    const currentDay = date.getDay();
    const distance   = (monday + 7 - currentDay) % 7;
    const newDate    = new Date(date.getTime());
    newDate.setDate(date.getDate() + distance);
    newDate.setHours(0, 0, 0, 0);
    return newDate;
}

> d = Date.now()
1545989455067
> nearestMonday(new Date(d)).getTime()
1546194600000
> m.unix(Date.now() / 1000).utc().startOf("isoWeek").valueOf()
1545609600000

Я нахожусь в зоне GMT ​​+ 530, что я могу изменить, чтобы получить тот же ответ, что и момент

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Хорошо, у нас есть несколько проблем:

Первое: часовые пояса

Дата работает с вашим местным часовым поясом, поэтому, когда вы делаете newDate.setHours(0, 0, 0, 0); и прочеетаким образом, он устанавливает объект на эти часы в вашем часовом поясе.Однако, когда вы делаете .getTime(), он возвращает миллис из эпохи в UTC.

Результат этого: если вы находитесь в gmt + 530 (Индия, я считаю), когда вы делаете .getTime () Миллис из эпохи будет отключен этой разницей (5 ч 30 м).

Чтобы компенсировать это, вы можете использовать getTimezoneOffset():

const nearestMonday = date => {
    const monday     = 1;
    const currentDay = date.getDay();
    const distance   = (monday + 7 - currentDay) % 7;
    const newDate    = new Date(date.getTime());
    newDate.setDate(date.getDate() + distance);
    newDate.setHours(0, 0, 0, 0);
    newDate.setTime(newDate.getTime()-1000*60*newDate.getTimezoneOffset());
    return newDate;
}

С другой стороны, ваш код, использующий момент, будет корректно работать с часовыми поясами, поэтому нет необходимости его менять.


Второй: какой понедельник?

Ваша функция nearestMonday вычисляет следующий Понедельник.

Функция startOf('isoWeek') устанавливает дату на понедельник текущей недели.

Если вы хотите, чтобы оба вычислили current , вам следует изменить nearestMonday следующим образом:

const nearestMonday = date => {
    const monday     = 1;
    const currentDay = date.getDay();
    const distance   = monday - currentDay;
    console.log('dist', distance);
    const newDate    = new Date(date.getTime());
    newDate.setDate(date.getDate() + distance);
    newDate.setHours(0, 0, 0, 0);
    newDate.setTime(newDate.getTime()-1000*60*newDate.getTimezoneOffset());
    return newDate;
}

Последнее: воскресенье?

getDay() в воскресенье вернет 0. Следовательно, «ближайший понедельник» будет днем ​​после этого.Я не исправил это, так как я не знаю, является ли это желаемым поведением, но отметил это только ради завершения

0 голосов
/ 28 декабря 2018

Я думаю, что это может делать то, что вы хотите:

const nearestMonday = date => {
    const day = 1000*60*60*24;
    const week = day*7;
    return new Date(Math.floor(date.getTime()/week)*week-3*day);
}
...