Как конвертировать дату JavaScript в UTC? - PullRequest
499 голосов
/ 04 июня 2009

Предположим, что пользователь вашего сайта вводит диапазон дат.

2009-1-1 to 2009-1-3

Вам необходимо отправить эту дату на сервер для некоторой обработки, но сервер ожидает, что все даты и время будут в UTC.

Теперь предположим, что пользователь находится на Аляске, Гавайях или Фиджи. Поскольку они находятся в часовом поясе, весьма отличном от UTC, диапазон дат необходимо преобразовать в нечто вроде этого:

2009-1-1T8:00:00 to 2009-1-4T7:59:59

Используя объект JavaScript Date, как бы вы преобразовали первый «локализованный» диапазон дат в то, что сервер поймет?

Ответы [ 24 ]

507 голосов
/ 21 июля 2011

Просто и глупо

var date = new Date(); 
var now_utc =  Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),
 date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());

 return new Date(now_utc);
323 голосов
/ 14 августа 2012

Метод toISOString() возвращает строку в упрощенном расширенном ISO формат ( ISO 8601 ), длина которого всегда 24 или 27 символов (YYYY-MM-DDTHH:mm:ss.sssZ или ±YYYYYY-MM-DDTHH:mm:ss.sssZ, соответственно). Часовой пояс всегда равен нулевому смещению UTC, как обозначено суффикс "Z".

Источник: MDN веб-документы

Необходимый формат создается методом .toISOString(). Для более старых браузеров (т.е. версии 8 и ниже), которые изначально не поддерживают этот метод, шим можно найти здесь :

Это даст вам возможность делать то, что вам нужно:

var isoDate = new Date('yourdatehere').toISOString();

Для работы с часовым поясом часовой пояс moment.js и moment.js являются действительно бесценными инструментами ... особенно для навигации по часовым поясам между клиентским и серверным JavaScript.

172 голосов
/ 15 августа 2012

Вот мой метод:

var now = new Date();
var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);

Полученный объект utc на самом деле не является датой UTC, но локальная дата смещена в соответствии с временем UTC (см. Комментарии). Однако на практике это делает свою работу.

24 голосов
/ 04 июня 2009
Date.prototype.toUTCArray= function(){
    var D= this;
    return [D.getUTCFullYear(), D.getUTCMonth(), D.getUTCDate(), D.getUTCHours(),
    D.getUTCMinutes(), D.getUTCSeconds()];
}

Date.prototype.toISO= function(){
    var tem, A= this.toUTCArray(), i= 0;
    A[1]+= 1;
    while(i++<7){
        tem= A[i];
        if(tem<10) A[i]= '0'+tem;
    }
    return A.splice(0, 3).join('-')+'T'+A.join(':');    
}
21 голосов
/ 20 февраля 2015

Конвертировать в ISO без изменения даты / времени

var now = new Date(); // Fri Feb 20 2015 19:29:31 GMT+0530 (India Standard Time) 
var isoDate = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString();
//OUTPUT : 2015-02-20T19:29:31.238Z

Преобразование в ISO с изменением даты / времени (дата / время будут изменены)

isoDate = new Date(now).toISOString();
//OUTPUT : 2015-02-20T13:59:31.238Z 

Fiddle link

18 голосов
/ 30 января 2013

Браузеры могут отличаться, и вы также должны помнить, что не следует доверять какой-либо информации, сгенерированной клиентом, при этом приведенное ниже утверждение работает для меня (Google Chrome v24 в Mac OS X 10.8.2)

var utcDate = new Date(new Date().getTime());


edit: "Чем это отличается от new Date()?" смотрите здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

  • Если аргументы не предоставлены, конструктор создает объект JavaScript Date для текущей даты и времени в соответствии с настройками системы.
  • Примечание. Если Date вызывается как конструктор с более чем одним аргументом, указанные аргументы представляют собой местное время. Если требуется UTC, используйте новую дату ( Date.UTC (...) ) с теми же аргументами. (примечание: Date.UTC () возвращает количество миллисекунд с 1970-01-01 00:00:00 UTC)

Добавление 60000 * Date.getTimezoneOffset (), как указано в предыдущих ответах, неверно. Во-первых, вы должны думать обо всех датах / временах как о времени UTC с модификатором часового пояса для целей отображения.

Опять же, браузеры могут отличаться, однако Date.getTime () возвращает количество миллисекунд с 1970-01-01 UTC / GMT. Если вы создадите новую дату, используя этот номер, как я делаю выше, это будет UTC / GMT. Однако, если вы отобразите его, вызвав .toString (), он окажется в вашем местном часовом поясе, потому что .toString () использует ваш местный часовой пояс, а не часовой пояс объекта Date, для которого он вызывается.

Я также обнаружил, что если вы вызываете .getTimezoneOffset () для даты, она возвращает ваш местный часовой пояс, а не часовой пояс объекта даты, для которого вы его вызвали (однако я не могу проверить, чтобы это было стандартным).

В моем браузере добавление 60000 * Date.getTimezoneOffset () создает DateTime, не UTC . Однако, когда отображается в моем браузере (например: .toString ()), он отображает DateTime в моем местном часовом поясе, который будет правильным временем UTC, если информация о часовом поясе игнорируется.

14 голосов
/ 04 июня 2009
var myDate = new Date(); // Set this to your date in whichever timezone.
var utcDate = myDate.toUTCString();
7 голосов
/ 04 июня 2009

Вы пытаетесь преобразовать дату в такую ​​строку?

Я бы сделать функцию, чтобы сделать это, и, хотя это немного спорно, добавить его к дате прототипа. Если вам неудобно делать это, то вы можете поместить это как отдельную функцию, передавая дату в качестве параметра.

Date.prototype.getISOString = function() {
    var zone = '', temp = -this.getTimezoneOffset() / 60 * 100;
    if (temp >= 0) zone += "+";
    zone += (Math.abs(temp) < 100 ? "00" : (Math.abs(temp) < 1000 ? "0" : "")) + temp;

    // "2009-6-4T14:7:32+10:00"
    return this.getFullYear()   // 2009
         + "-"
         + (this.getMonth() + 1) // 6
         + "-"
         + this.getDate()       // 4
         + "T"
         + this.getHours()      // 14
         + ":"
         + this.getMinutes()    // 7
         + ":"
         + this.getSeconds()    // 32
         + zone.substr(0, 3)    // +10
         + ":"
         + String(temp).substr(-2) // 00
    ;
};

Если вам это нужно во время UTC, просто замените все функции get * на getUTC *, например: getUTCFullYear, getUTCMonth, getUTCHours ..., а затем просто добавьте "+00: 00" в конце вместо часового пояса пользователя. смещение.

7 голосов
/ 01 июля 2015

Моя рекомендация при работе с датами заключается в разборе даты на отдельные поля из пользовательского ввода. Вы можете использовать его как полную строку, но вы играете с огнем.

JavaScript может обрабатывать две одинаковые даты в разных форматах по-разному.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse

Никогда не делай ничего подобного:

new Date('date as text');

Как только ваша дата будет проанализирована в отдельных полях из пользовательского ввода, создайте объект даты. Как только объект даты создан, преобразуйте его в UTC, добавив смещение часового пояса. Я не могу не подчеркнуть, насколько важно использовать смещение от объекта даты из-за перехода на летнее время (однако это еще одно обсуждение, чтобы показать, почему).

var year = getFullYear('date as text');
var month = getMonth('date as text');
var dayOfMonth = getDate('date as text');

var date = new Date(year, month, dayOfMonth);

var offsetInMs = ((date.getTimezoneOffset() * 60)  // Seconds
                 * 1000);                          //  Milliseconds

var utcDate = new Date(date.getTime + offsetInMs);

Теперь вы можете передавать дату на сервер в формате UTC. Опять же, я бы настоятельно рекомендовал не использовать любые строки даты. Либо передайте его на сервер с минимальной степенью детализации, необходимой вам, например. год, месяц, день, минута или значение, например, миллисекунды эпохи Unix.

7 голосов
/ 28 июня 2012
date = '2012-07-28'; stringdate = new Date(date).toISOString();

должен работать в большинстве новых браузеров. он возвращает 2012-07-28T00:00:00.000Z в Firefox 6.0

...