Как ISO 8601 форматирует дату со смещением часовой пояс в JavaScript?
Цель: Найти local time
и UTC time offset
local time
UTC time offset
затем построить URL в следующем формате.
Пример URL: /Actions/Sleep? Duration = 2002-10-10T12: 00: 00−05: 00
Формат основан на рекомендации W3C: http://www.w3.org/TR/xmlschema11-2/#dateTime
В документации сказано:
Например, 2002-10-10T12: 00: 00−05: 00 (полдень 10 октября 2002 года, центральное летнее время, а также стандартное восточное время в США) равно 2002-10-10T17: 00: 00Z, пять часов позже, чем 2002-10-10T12: 00: 00Z.
Исходя из моего понимания, мне нужно найти свое местное время с помощью новой функции Date(), затем использовать функцию getTimezoneOffset() для вычисления разницы, а затем присоединить ее к концу строки.
1. Получите местное время в формате
var local = new Date().format("yyyy-MM-ddThh:mm:ss"); //today (local time)
выход
2013-07-02T09:00:00
Смещение времени UTC 2.Get на час
var offset = local.getTimezoneOffset() / 60;
выход
7
3.Создание URL (только временная часть)
var duration = local + "-" + offset + ":00";
выход:
2013-07-02T09:00:00-7:00
Вышеуказанный вывод означает, что мое местное время 2013/07/02 9 утра, а разница с UTC составляет 7 часов (UTC на 7 часов опережает местное время)
Пока что это работает, но что если getTimezoneOffset() возвращает отрицательное значение, например -120?
Мне интересно, как должен выглядеть формат в таком случае, потому что я не могу понять из документа W3C. Заранее спасибо.
Ответы
Ответ 1
Ниже должно работать правильно, и для всех браузеров (благодаря @MattJohnson для подсказки)
Date.prototype.toIsoString = function() {
var tzo = -this.getTimezoneOffset(),
dif = tzo >= 0 ? '+' : '-',
pad = function(num) {
var norm = Math.floor(Math.abs(num));
return (norm < 10 ? '0' : '') + norm;
};
return this.getFullYear() +
'-' + pad(this.getMonth() + 1) +
'-' + pad(this.getDate()) +
'T' + pad(this.getHours()) +
':' + pad(this.getMinutes()) +
':' + pad(this.getSeconds()) +
dif + pad(tzo / 60) +
':' + pad(tzo % 60);
}
var dt = new Date();
console.log(dt.toIsoString());
Ответ 2
getTimezoneOffset()
возвращает противоположный знак формата, требуемого спецификацией, на которую вы ссылались.
Этот формат также известен как ISO8601 или, точнее, RFC3339.
В этом формате UTC представлен Z
, а все остальные форматы представлены смещением от UTC. Значение такое же, как JavaScript, но порядок вычитания инвертирован, поэтому результат несет противоположный знак.
Кроме того, нет никакого метода на нативном объекте Date
, который называется format
, поэтому ваша функция в # 1 завершится неудачно, если вы не используете библиотеку для достижения этой цели. См. эту документацию.
Если вы ищете библиотеку, которая может работать с этим форматом напрямую, я рекомендую попробовать moment.js. Фактически, это формат по умолчанию, поэтому вы можете просто сделать это:
var m = moment(); // get "now" as a moment
var s = m.format(); // the ISO format is the default so no parameters are needed
// sample output: 2013-07-01T17:55:13-07:00
Это хорошо протестированное кросс-браузерное решение и имеет множество других полезных функций.
Ответ 3
Это моя функция для часового пояса клиентов, это вес и простой
function getCurrentDateTimeMySql() {
var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, 19).replace('T', ' ');
var mySqlDT = localISOTime;
return mySqlDT;
}
Ответ 4
Просто мои два посылает сюда
Я столкнулся с этой проблемой с datetime, так что я сделал это:
const moment = require('moment-timezone')
const date = moment.tz('America/Bogota').format()
Затем сохраните дату в БД, чтобы иметь возможность сравнить ее с каким-либо запросом.
Чтобы установить moment-timezone
npm i moment-timezone
Ответ 5
Проверь это:
function dateToLocalISO(date) {
const off = date.getTimezoneOffset()
const absoff = Math.abs(off)
return (new Date(date.getTime() - off*60*1000).toISOString().substr(0,23) +
(off > 0 ? '-' : '+') +
(absoff / 60).toFixed(0).padStart(2,'0') + ':' +
(absoff % 60).toString().padStart(2,'0'))
}
// Test it:
d = new Date()
dateToLocalISO(d)
// ==> '2019-06-21T16:07:22.181-03:00'
// Is similar to:
moment = require('moment')
moment(d).format('YYYY-MM-DDTHH:mm:ss.SSSZ')
// ==> '2019-06-21T16:07:22.181-03:00'