Объекты MomentJS и JS Date не ссылаются на один и тот же час - PullRequest
0 голосов
/ 14 октября 2019

У меня есть экземпляр сервера (NodeJS), который получает набор объектов и планирует их отправку push-уведомлений пользователям.

Некоторые из этих объектов являются периодическими, и эта периодичность обрабатываетсястрока вроде этого:

90=>Mon&Tue&Thu=>16:00

Что читается как:

offset_minutes=>days_of_the_week=>initial_hour

Затем я проверяю, совпадает ли текущий день с одним из заданных дней в строке,а затем измените дату на указанный час в «initial_hour» и, наконец, вычтите количество минут «offset_minutes» из объекта Date.

Кажется, до сих пор просто, верно? Ну, не так много. Давайте сначала посмотрим код:

const isToday = weekDays.split("&")
            .map(a => {
                switch (a) {
                    case 'Mon': return 1;
                    case 'Tue': return 2;
                    case 'Wed': return 3;
                    case 'Thu': return 4;
                    case 'Fri': return 5;
                    case 'Sat': return 6;
                    case 'Sun': return 7;
                }
            })
            .some(v => v == currentDay);

        if (isToday) {

            let finalDate = moment(today)
                .set("hour", Number(hour))
                .set("minute", Number(mins));


            if (offset) {
             finalDate.subtract('minutes', Number(offset));
            }


            return finalDate.toDate();

Все работает хорошо, пока я не выполню преобразования MomentJS. Когда я выводю объект Date с помощью метода .toDate (), этот объект всегда устанавливается на 2 часа раньше ожидаемого времени . Но если я использую метод .toISOString (), я получаю подходящее время для всех случаев.

Полагаю, что-то не так с моими объектами Date, настроив их в другом часовом поясе, чем тот, который у меня есть. Несколько примеров:

  • Для строки 90=>Mon&Tue&Thu=>16:00 Я получаю объект Date: 2019-10-14T14:00:11.852Z
  • Для строки 30=>Mon&Tue&Wed&Thu&Fri&Sat&Sun=>18:30 Я получаю объект Date: 2019-10-14T16:30:11.866Z

Я хотел бы знать, что объясняет такое поведение, и если я могу что-то сделать, чтобы изменить его так, чтобы обычный объект Javascript Date указывал на тот же час, что и мой объект momentjs, или. toISOString () вывод.

Спасибо!

1 Ответ

0 голосов
/ 14 октября 2019

Размещенный код неполный и не демонстрирует описанную проблему.

Я переопределил код без moment.js, как мог, и упростил его. Вроде нормально работает:

function parseThing(s) {
  // Parse input string
  let b = s.split('=>');
  let offset = +b[0];
  let days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
  let weekDays = b[1].split('&').map(day => days.indexOf(day));
  let [hr, min] = b[2].split(':');

  // Get a date for today
  let date = new Date();

  // If today included, return an adjusted date
  if (weekDays.includes(date.getDay())) {
    date.setHours(hr, min, 0, 0);

    if (offset) {
      date.setMinutes(date.getMinutes()+ Number(offset));
    }

    return date;
  }

  // If today isn't included, return null
  return null;
}

let s0 = '90=>Mon&Tue&Thu=>16:00';
let s1 = '0=>Mon&Tue&Wed&Thu&Fri&Sat&Sun=>18:30';

console.log(parseThing(s0).toString());
console.log(parseThing(s1).toString());

Если местный день является одним из тех, что в строке (пн, вт, чт), он возвращает дату, эквивалентную местному времени 17:30, что составляет 90минутное смещение от 16:00, что кажется правильным.

PS Я изменил воскресенье на 0, так как не вижу смысла в том, чтобы оно равнялось 7. Также секунды и миллисекунды также обнуляются.

...