Как определить локальный часовой пояс при синтаксической обработке строки даты ISO 8601?
У меня есть строка даты ISO, как показано ниже
var startTimeISOString = "2013-03-10T02:00:00Z";
когда я конвертирую его в объект date в javascript, используя приведенный ниже код, он возвращает
var startTimeDate = new Date(startTimeISOString);
o/p
Date {Sun Mar 10 2013 07:30:00 GMT+0530 (India Standard Time)}
Он уверен, преобразует ISOString на дату, но он преобразуется в локальное время, так как новая Date() зависит от клиента. Как просто преобразовать строку даты даты iso в дату и время, но не в локальное время даты.?
Спасибо
Ответы
Ответ 1
Согласно MDN:
Различия в предполагаемой временной зоне
Учитывая строку даты "7 марта 2014 года", parse() принимает локальное время зоны, но, учитывая формат ISO, такой как "2014-03-07", он примет часовой пояс UTC. Поэтому объекты Date, созданные с использованием этих строк будут представлять разные моменты времени, если система не установлена с локальный часовой пояс UTC. Это означает, что появляются две строки даты эквивалент может привести к двум различным значениям в зависимости от формата строки, которая преобразуется (это поведение изменяется в ECMAScript ed 6, так что оба будут рассматриваться как локальные).
Я сделал это так и теперь получаю точное время, которое находится внутри строки даты ISO вместо локального времени
var startTimeISOString = "2013-03-10T02:00:00Z";
var startTime = new Date(startTimeISOString );
startTime = new Date( startTime.getTime() + ( startTime.getTimezoneOffset() * 60000 ) );
Это приведет к тому же дате времени внутри строки даты iso, вывод здесь
о/р
Date {Sun Mar 10 2013 02:00:00 GMT+0530 (India Standard Time)}
Ответ 2
Подводя итог разговору из сообщения tracevipin:
Все объекты Date основаны на значение времени, которое равно миллисекундам с 1970-01-01T00: 00: 00Z, поэтому они являются UTC на их ядро. Это отличается от UNIX, который использует значение, представляющее секунды с той же эпохи.
Метод Date.prototype.toString возвращает строку, зависимую от реализации, которая представляет время, основанное на системных настройках и смещении часового пояса клиента ( ака локального времени).
Если требуется временная строка UTC ISO8601, можно использовать метод Date.prototype.toISOString. Очень легко написать "прокладку" для этих методов, если это необходимо.
И наконец, не доверяйте Date.parse для синтаксического анализа строки. Поддержка UTC-строки формата ISO8601 указана в ES5, однако она не выполняется последовательно в браузерах. Гораздо лучше разобрать строку вручную (это не сложно, есть примеры на SO о том, как это сделать), если требуется широкая поддержка браузера (например, типичное веб-приложение).
Простой маркер времени маркера UTC ISO8601:
function dateObjectFromUTC(s) {
s = s.split(/\D/);
return new Date(Date.UTC(+s[0], --s[1], +s[2], +s[3], +s[4], +s[5], 0));
}
и здесь прокладка для toISOString:
if (typeof Date.prototype.toISOString != 'function') {
Date.prototype.toISOString = (function() {
function z(n){return (n<10? '0' : '') + n;}
function p(n){
n = n < 10? z(n) : n;
return n < 100? z(n) : n;
}
return function() {
return this.getUTCFullYear() + '-' +
z(this.getUTCMonth() + 1) + '-' +
z(this.getUTCDate()) + 'T' +
z(this.getUTCHours()) + ':' +
z(this.getUTCMinutes()) + ':' +
z(this.getUTCSeconds()) + '.' +
p(this.getUTCMilliseconds()) + 'Z';
}
}());
}
Ответ 3
Это происходит потому, что дата печатается с использованием метода toString
, который по умолчанию возвращает дату и время в локальном часовом поясе. Метод toUTCString
предоставит вам нужную вам строку.
Date
фактически сохраняет дату как unix-время в миллисекундах и предоставляет методы для ее управления.
Ответ 4
В vanilla javascript нет способа создать дату, предполагающую местное время отформатированной строки ISO, которую вы ему даете. Вот что происходит, когда вы передаете форматированную строку ISO 8601 в javascript. Я собираюсь использовать время без UTC, поскольку оно иллюстрирует проблему лучше, чем использование форматированной в ISO строки:
- var startTime = новая дата ( "2013-03-10T02: 00: 00 + 06: 00" ). Обратите внимание, что это также может быть "2013-03-10T02: 00: 00Z" или любая другая форматированная строка ISO.
- прочитайте время, примените смещение и вычислите миллисекунды с 1970-01-01T00: 00: 00Z
- Теперь у вас есть только миллисекунды - вы потеряли всю информацию о часовом поясе. В этом случае 1362859200000
Все функции, кроме тех, которые дают вам UTC-представление этого числа, будут использовать часовой пояс компьютера, на котором выполняется код, чтобы интерпретировать этот номер как время.
Чтобы сделать то, что хочет исходный плакат, вам нужно.
- проанализировать строку ISO, интерпретировать смещение ('Z' или '+06: 00') в качестве смещения часового пояса
- сохранить смещение часового пояса
- вычисляет и сохраняет мс с эпохи, используя смещение смещения временной шкалы
- удерживайте это смещение
- всякий раз, когда вы пытаетесь выполнить расчет или распечатать дату, примените смещение часового пояса.
Это не тривиально и требует полной интерпретации спецификации 8601. Путь слишком много кода, чтобы положить здесь.
Это именно то, что нужно moment.js. Я настоятельно рекомендую использовать его. Использование момента .js:
moment("2013-03-10T02:00:00Z").format()
"2013-03-10T02:00:00Z"
это приведет к печати времени ISO исходной строки, сохраняя смещение.