Странное поведение «новой даты (Date.UTC)»

Странное поведение new Date(Date.UTC(...)) при конвертации даты из универсальное глобальное время в пользовательскую местное время

У меня есть временная метка, полученная с сервера, похожего на 2019-02-01 14:28:16, и я пытаюсь безопасно преобразовать эту временную метку в местное время пользователей, чтобы избежать ошибки Недействительная дата.

Но, что удивительно, он преобразует 1 февраля в 5 февраля. Вот сценарий:

const myDate = new Date('2019-02-01 14:28:16');

console.info('Step 1: MyDate: ' + myDate.toString());

const utcFormateOfMyDate = Date.UTC(
  myDate.getFullYear(),
  myDate.getMonth(),
  myDate.getDay(),
  myDate.getHours(),
  myDate.getMinutes(),
  myDate.getSeconds(),
  myDate.getMilliseconds()
);

console.info('Step 2: utcFormateOfMyDate: ' + utcFormateOfMyDate.toString()); // 1549376896000

console.info('Step 3.1 => ' + new Date(utcFormateOfMyDate)); // Tue Feb 05 2019 19:28:16 GMT+0500 (Pakistan Standard Time 

console.info('Step 3.2 => ' + Date(utcFormateOfMyDate)); // Fri Feb 01 2019 19:43:36 GMT+0500 (Pakistan Standard Time)

Единственное изменение, которое я сделал, просто добавил ключевое слово новый, а преобразованная отметка времени перескочила с 1 февраля на 5 февраля (в будущем); обратитесь к скриншоту

Странное поведение «новой даты (Date.UTC)»

Хотя удаление нового ключевого слова решило проблему, но я не смог найти объяснение этому магическому эффекту. Может ли кто-нибудь помочь мне понять это поведение?

Нет необходимости «конвертировать» дату. Внутри это всегда UTC.

Pointy 01.02.2019 16:04

Я получаю дату в нескольких форматах; даже Invalid Dates, поэтому в целях безопасности я сделал преобразование в обход плохих форматов. Но я обнаруживаю это волшебное поведение с new и без ключевого слова ~new~

mumair 01.02.2019 16:07

Проблема в том, что вы звоните getDay() вместо getDate().

Pointy 01.02.2019 16:08

Для Date.UTC(utcFormatOfMyDate) это выглядит так, как будто функция просто полностью игнорирует значение года вне допустимого диапазона.

Pointy 01.02.2019 16:10

удивительно, ты прав

mumair 01.02.2019 16:10
getDay() означает «день недели» — я часто делаю эту ошибку :)
Pointy 01.02.2019 16:11

@Pointy Я думаю, что мы все это делаем. Я не могу вспомнить время, когда мне приходилось выводить день из объекта Date, и меня не смущал этот метод...

VLAZ 01.02.2019 16:12

Во-первых, вам не следует делать new Date('2019-02-01 14:28:16'); - неясно, является ли это местным временем или UTC, и разные браузеры (версии) ведут себя по-разному. Вместо этого используйте явный new Date('2019-02-01T14:28:16Z'); и не беспокойтесь о каких-либо «конверсиях».

Bergi 01.02.2019 16:21

@Bergi хороший момент, но отметка времени не в моей власти; Я получаю разные форматы, такие как (системные мельницы, строка, '2019-02-01T14:28:16Z', даже недопустимые даты :)) проблема была getDay() вместо getDate() в преобразовании UTC

mumair 01.02.2019 16:24
Поведение ключевого слова "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
9
78
1

Ответы 1

Как отмечалось в комментариях, проблема заключается в том, что вы сравниваете яблоки и апельсины, случайно передавая значение Date.getDay (вместо Date.getDate) на Date.UTC. и сравнение результата с выходными данными прямого анализа метки времени. Тем не менее, вы не должны полагаться на new Date() или Date() для анализа временной метки, так как реализации браузеров различаются, и вы можете получить противоречивые результаты.

Вместо этого вы можете сделать что-то вроде следующего с форматом метки времени, который вы получаете от сервера:

const timestamp = '2019-02-01 14:28:16';
const [y, m, d, hh, mm, ss] = timestamp.match(/\d+/g);
const date = new Date(Date.UTC(y, m - 1, d, hh, mm, ss));
console.info(JSON.stringify(date));

// date as UTC string
console.info(date.toUTCString());

// date as local string
console.info(date.toString());

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