Подтвердить что ты не робот

Как 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. Заранее спасибо.

4b9b3361

Ответ 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'