Как я могу конвертировать дату в GMT?

Как конвертировать дату разных часовых поясов в GMT 0? Скажем, у меня есть даты, подобные этому

Fri Jan 20 2012 11:51:36 GMT-0500
Fri Jan 20 2012 11:51:36 GMT-0300
Fri Jan 20 2012 11:51:36 GMT+0500

в

Fri Jan 20 2012 06:51:36 GMT
Fri Jan 20 2012 08:51:36 GMT
Fri Jan 20 2012 16:51:36 GMT

это даты, которые я получаю через new Date().toString() в разных часовых поясах. Есть ли какой-либо js-метод для определения временной зоны и преобразования соответственно?

РЕДАКТИРОВАТЬ: Вторые три даты - это не GMT-настроенные времена первых трех. Например, Fri Jan 20 2012 11:51:36 GMT-0500 в GMT - Fri Jan 20 2012 16:51:36 GMT не Fri Jan 20 2012 06:51:36 GMT. GMT-0500 отстает от GMT, а не впереди, поэтому вам нужно добавить смещение, чтобы получить GMT, а не вычесть его.

Ответ 1

Вы можете использовать Date.getTimezoneOffset(). Это возвращает разницу во времени между вашей датой и GMT в минутах.

Умножьте это на 60 000 (миллисекунды в минуту), чтобы получить миллисекунды и вычесть из даты, чтобы создать новую дату.

new Date(date.valueOf() + date.getTimezoneOffset() * 60000);

Ответ 2

Вы можете просто использовать методы toUTCString (или toISOString) объекта даты.

Пример:

new Date("Fri Jan 20 2012 11:51:36 GMT-0500").toUTCString()

// Output:  "Fri, 20 Jan 2012 16:51:36 GMT"

Если вы предпочитаете лучше контролировать формат вывода, подумайте об использовании библиотеки, такой как date-fns или moment.js.

Кроме того, в вашем вопросе вы на самом деле неправильно преобразовали время. Когда смещение отображается в строке метки времени, это означает, что значения даты и времени в строке уже были откорректированы с помощью UTC на это значение. Чтобы преобразовать обратно в UTC, инвертируйте знак перед применением смещения.

11:51:36 -0300  ==  14:51:36Z

Ответ 3

Хотя это выглядит логично, принятый ответ неверен, потому что даты JavaScript не работают так.

Здесь очень важно отметить, что числовое значение даты (т.е. new Date()-0 или Date.now()) в JavaScript всегда измеряется как миллисекунды с эпохи, которая является количеством без часовой пояс, основанным на точное точное мгновение в истории Вселенной. Вам не нужно добавлять или вычитать что-либо в числовое значение, возвращаемое из Date() чтобы преобразовать числовое значение в часовой пояс, поскольку числовое значение не имеет часовой пояс. Если у него есть часовой пояс, все остальное в датах JavaScript не будет работать.

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

Ниже приведены примеры того, как числовое значение даты (предоставленное конструктору даты) не зависит от часового пояса:

В центральное стандартное время:

new Date(0);
// Wed Dec 31 1969 18:00:00 GMT-0600 (CST)

В Анкоридже, Аляска:

new Date(0);
// Wed Dec 31 1969 15:00:00 GMT-0900 (AHST)

В Париже, Франция:

new Date(0);
// Thu Jan 01 1970 01:00:00 GMT+0100 (CET)

Крайне важно заметить, что во ВСЕХ случаях, в зависимости от времени, свободного от времени, времени смещения нулевого миллисекунды, результирующее время идентично. 1 час ночи в Париже, Франция - тот же самый момент, что и в 3 часа дня в Анкоридже, штат Аляска, который является тем же самым моментом, что и в 18:00 в Чикаго, штат Иллинойс.

По этой причине принятый ответ на этой странице неверен. Заметим:

// Create a date.
   date = new Date();
// Fri Jan 27 2017 18:16:35 GMT-0600 (CST)


// Observe the numerical value of the date.
   date.valueOf();
// 1485562595732
// n.b. this value has no timezone and does not need one!!


// Observe the incorrectly "corrected" numerical date value.
   date.valueOf() + date.getTimezoneOffset() * 60000;
// 1485584195732


// Try out the incorrectly "converted" date string.
   new Date(date.valueOf() + date.getTimezoneOffset() * 60000);
// Sat Jan 28 2017 00:16:35 GMT-0600 (CST)

/* Not the correct result even within the same script!!!! */

Если у вас есть строка даты в другом часовом поясе, преобразование в результирующий объект, созданный new Date("date string") не требуется. Зачем? Числовое значение JavaScript этой даты будет одинаковым независимо от его часовой пояс. JavaScript автоматически проходит через удивительно сложные процедуры для извлечения исходного количества миллисекунд с эпохи, независимо от того, каков был исходный часовой пояс.

Суть в том, что включение текстовой строки даты x в new Date(x) автоматически преобразуется из исходного часового пояса, независимо от того, что могло бы быть, в временное время без миллисекунд, представляющее время, которое является одинаковым независимо от любого часового пояса, В вашем фактическом приложении вы можете отображать дату в любом часовом поясе, который вы хотите, но НЕ добавляйте/вычитаете числовое значение даты, чтобы сделать это. Все преобразования уже произошли в момент создания объекта даты. Часового пояса уже нет, потому что объект даты создается с использованием точно определенного времени и времени, свободного от времени.

Часовой пояс только начинает существовать снова, когда рассматривается пользователь вашей заявки. У пользователя есть часовой пояс, поэтому вы просто показываете этот часовой пояс для пользователя. Но это также происходит автоматически.

Давайте рассмотрим пару дат в вашем исходном вопросе:

   date1 = new Date("Fri Jan 20 2012 11:51:36 GMT-0300");
// Fri Jan 20 2012 08:51:36 GMT-0600 (CST)


   date2 = new Date("Fri Jan 20 2012 11:51:36 GMT-0300")
// Fri Jan 20 2012 08:51:36 GMT-0600 (CST)

Консоль уже знает мой часовой пояс, и поэтому она автоматически показала мне, что для меня означают те времена.

И если вы хотите узнать время в GMT/UTC, также не требуется конвертация! Вы совсем не меняете время. Вы просто показываете строку UTC времени:

    date1.toUTCString();
// "Fri, 20 Jan 2012 14:51:36 GMT"

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

Ответ 4

Просто используйте семейство методов Date.getUTC*(). На моем компьютере (CET, UTC + 01: 00):

new Date().toString()
//Fri Jan 20 2012 18:05:16 GMT+0100 (CET)

new Date().getHours()
//18

new Date().getUTCHours()
//17

Обратите внимание, что getUTCHours() возвращает правильный час в UTC.

Смотрите также:

Ответ 5

Я просто работал над этим, возможно, я немного опоздал, но я сделал обходной путь. Вот шаги: - Получить текущее время из любого часового пояса приложения. - Получить смещение часового пояса этой зоны от gmt 0. затем добавить значение часового пояса в милисекундах. Вы получите дату в своем часовом поясе. Я добавил дополнительный код, чтобы удалить что-либо по истечении фактического времени.

getCurrentDate() {
    var date = new Date();
    var newDate = new Date(8 * 60 * 60000 + date.valueOf() + 
                           (date.getTimezoneOffset() * 60000));
    var ampm = newDate.getHours() < 12 ? ' AM' : ' PM';
    var strDate = newDate + '';
    return (strDate).substring(0, strDate.indexOf(' GMT')) + ampm
}

Ответ 6

GMTDate = new Date(). ToGMTString();

Ответ 7

Я пытаюсь с ниже. Кажется, это работает нормально. Существуют ли какие-либо ограничения для этого подхода? Пожалуйста подтвердите.

var now=new Date();                         // Sun Apr 02 2017 2:00:00 GMT+1000 (AEST)
var gmtRe = /GMT([\-\+]?\d{4})/;
var tz = gmtRe.exec(now)[1];               // +1000
var hour=tz/100;                           // 10
var min=tz%100;                            // 0
now.setHours(now.getHours()-hour);
now.setMinutes(now.getMinutes()-min);      // Sat Apr 01 2017 16:00:00 GMT

Ответ 8

Основываясь на принятом ответе и втором наивысшем скоринговом ответе, оба не идеальны в соответствии с комментарием, поэтому я смешал оба, чтобы получить что-то совершенное:

var date = new Date(); //Current timestamp
date = date.toGMTString(); 
//Based on the time zone where the date was created
console.log(date);

/*based on the comment getTimezoneOffset returns an offset based 
on the date it is called on, and the time zone of the computer the code is
 running on. It does not supply the offset passed in when constructing a 
date from a string. */

date = new Date(date); //will convert to present timestamp offset
date = new Date(date.getTime() + (date.getTimezoneOffset() * 60 * 1000)); 
console.log(date);