Создать дату с установленным часовым поясом без использования строкового представления

413

У меня есть веб-страница с тремя выпадающими списками для дня, месяца и года. Если я использую Dateконструктор JavaScript, который принимает числа, то я получаю Dateобъект для моего текущего часового пояса:

new Date(xiYear, xiMonth, xiDate)

Дайте правильную дату, но она думает, что дата - GMT + 01: 00 из-за перехода на летнее время.

Проблема здесь в том, что я затем передаю это Dateметоду Ajax, и когда дата десериализируется на сервере, она конвертируется в GMT и теряет час, который перемещает день назад на единицу. Теперь я могу просто передать день, месяц и год по отдельности в метод Ajax, но, похоже, должен быть лучший путь.

Принятый ответ указал мне верное направление, однако setUTCHours()изменилось только само использование:

Apr 5th 00:00 GMT+01:00 

в

Apr 4th 23:00 GMT+01:00

Затем я также должен был установить дату UTC, месяц и год, чтобы в конечном итоге

Apr 5th 01:00 GMT+01:00

что я и хотел

Дэн
источник
9
Если принятый ответ указал вам верное направление, но не ответил на ваш вопрос, я бы сказал, что это не должен быть принятый ответ. Ответ должен ответить на заданный вопрос.
TWR Коул

Ответы:

481

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

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

Используя new Date(Date.UTC(year, month, day, hour, minute, second))вы можете создать объект Date из определенного времени UTC.

Jishi
источник
101
Синтаксис «Новая дата (Date.UTC (...))» позволяет вам создавать дату, которая эквивалентна дате UTC с точки зрения момента времени, который он представляет, но это не то же самое - он имеет другой (не UTC) часовой пояс.
Энтони
52
Имейте в виду, что при использовании «Date» значение «month» имеет диапазон от 0 до 11 (не от 1 до 12). Я продолжал получать смещение часового пояса 2 часа (хотя это должно было быть 1 час), и мне потребовались часы, чтобы узнать, что причина была неправильным месяцем.
Select0r
4
Этот ответ великолепен. Но я использую библиотеку [datepicker ui], которая использует новую дату во многих местах. Все, что я хочу, это установить часовой пояс UTC, и каждая дата соответствует новому часовому поясу. Я удивлен, что у Javascript нет ничего для этого.
Санджив Кумар Данги
6
@ jishi - объекты даты основаны на времени по Гринвичу, а не по местному времени. Однако стандартный метод Date.prototype.toString будет отображать значения местного времени.
RobG
5
@ Энтони - « но это не то же самое время » - это неправильно. Он представляет собой точно такой же момент времени, единственное отличие - это смещение часового пояса.
RobG
199
var d = new Date(xiYear, xiMonth, xiDate);
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );

Этот ответ специально разработан для исходного вопроса и не даст того ответа, который вы обязательно ожидаете. В частности, некоторые люди захотят вычесть смещение часового пояса, а не добавить его. Помните, однако, что весь смысл этого решения состоит в том, чтобы взломать объект даты javascript для конкретной десериализации, а не быть правильным во всех случаях.

TWR Коул
источник
62
@gthmb конечно, но я чувствую, что *60*1000в этом случае это понятнее; другими словами, это довольно очевидно, почему это там.
TWR Коул
22
Это почти работает для меня, за исключением того, что я должен использовать - (минус) вместо + (плюс), чтобы получить правильное время для моего часового пояса.
Wytze
3
Да, как уже отмечали другие - я думаю, что в этом ответе есть ошибка. Должен быть минус, а не плюс.
UpTheCreek
3
Согласно developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… значение, возвращаемое getTimezoneOffset, подписывается в соответствии с фактическим смещением в вашей локали на момент вызова функции, в том числе с учетом DST, поэтому я не понимаю, почему вам нужно вычесть это.
TWR Cole
15
Если вы добавите timezoneOffset к объекту даты, его значение, отформатированное в местном часовом поясе, будет выглядеть как правильное значение в UTC, но у него все еще будет исходное смещение часового пояса (и некоторые представления, такие как «ISOString», будут фактически отображать его). Поэтому в зависимости от того, как вы затем сериализуете объект даты, JS может снова применить смещение часового пояса , что даст вам неправильный ответ. Я считаю, что это ответственно за путаницу в этих комментариях между +/-. В любом случае, мое отрицательное мнение относится к этому факту, а также к тому, что «в большинстве случаев вы получаете то, что ожидаете».
metamatt
173

Я считаю, что вам нужна функция createDateAsUTC (пожалуйста, сравните с convertDateToUTC )

function createDateAsUTC(date) {
    return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
}

function convertDateToUTC(date) { 
    return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); 
}
monsterclub
источник
36
Я поражен его ясностью и полезностью ответа. Не знал, что работа с датами Javascript была таким кошмаром до сегодняшнего дня: S
will824
Не могли бы вы объяснить разницу между ними? Первый конвертируется dateв часовой пояс UTC, но второй, кажется, не делает ничего полезного? (возвращает ту же дату, что и date)
Джонатан Лин
4
Теперь я понял: первое возвращает дату в часовом поясе UTC с буквальными значениями даты местного времени. Вторая возвращает дату в местном часовом поясе, но с буквенными значениями даты UTC.
Джонатан Лин
8
Этот подход является одной из реализаций шаблона, называемого «сдвиг эпохи», который предназначен для перемещения эпохи (то есть на основе UTC) к той, которая смещена на текущее смещение часового пояса. К сожалению, несмотря на то, что это обычно видно, такой подход имеет недостатки. DateОбъект JavaScript всегда будет отражать эпоху Unix на основе UTC и местный часовой пояс. Симптом становится очевидным, когда вы вызываете toStringполученный объект даты и по-прежнему видите местный часовой пояс, даже если вы ожидали, что он будет в формате UTC.
Мэтт Джонсон-Пинт
2
Это также может привести к ошибкам в значениях времени вблизи переходов на летнее время в местном часовом поясе. Короче говоря, смещение эпох (через любую реализацию) не работает с Dateобъектом JavaScript . Еще один способ увидеть это здесь - это Date.UTCожидание значений на основе UTC, и вы передаете им значения местного времени, и наоборот, с помощью Dateконструктора.
Мэтт Джонсон-Пинт
70

Просто установите часовой пояс и вернитесь в соответствии

new Date().toLocaleString("en-US", {timeZone: "America/New_York"})

Другие часовые пояса следующие

var world_timezones =
[
    'Europe/Andorra',
    'Asia/Dubai',
    'Asia/Kabul',
    'Europe/Tirane',
    'Asia/Yerevan',
    'Antarctica/Casey',
    'Antarctica/Davis',
    'Antarctica/DumontDUrville', 
    'Antarctica/Mawson',
    'Antarctica/Palmer',
    'Antarctica/Rothera',
    'Antarctica/Syowa',
    'Antarctica/Troll',
    'Antarctica/Vostok',
    'America/Argentina/Buenos_Aires',
    'America/Argentina/Cordoba',
    'America/Argentina/Salta',
    'America/Argentina/Jujuy',
    'America/Argentina/Tucuman',
    'America/Argentina/Catamarca',
    'America/Argentina/La_Rioja',
    'America/Argentina/San_Juan',
    'America/Argentina/Mendoza',
    'America/Argentina/San_Luis',
    'America/Argentina/Rio_Gallegos',
    'America/Argentina/Ushuaia',
    'Pacific/Pago_Pago',
    'Europe/Vienna',
    'Australia/Lord_Howe',
    'Antarctica/Macquarie',
    'Australia/Hobart',
    'Australia/Currie',
    'Australia/Melbourne',
    'Australia/Sydney',
    'Australia/Broken_Hill',
    'Australia/Brisbane',
    'Australia/Lindeman',
    'Australia/Adelaide',
    'Australia/Darwin',
    'Australia/Perth',
    'Australia/Eucla',
    'Asia/Baku',
    'America/Barbados',
    'Asia/Dhaka',
    'Europe/Brussels',
    'Europe/Sofia',
    'Atlantic/Bermuda',
    'Asia/Brunei',
    'America/La_Paz',
    'America/Noronha',
    'America/Belem',
    'America/Fortaleza',
    'America/Recife',
    'America/Araguaina',
    'America/Maceio',
    'America/Bahia',
    'America/Sao_Paulo',
    'America/Campo_Grande',
    'America/Cuiaba',
    'America/Santarem',
    'America/Porto_Velho',
    'America/Boa_Vista',
    'America/Manaus',
    'America/Eirunepe',
    'America/Rio_Branco',
    'America/Nassau',
    'Asia/Thimphu',
    'Europe/Minsk',
    'America/Belize',
    'America/St_Johns',
    'America/Halifax',
    'America/Glace_Bay',
    'America/Moncton',
    'America/Goose_Bay',
    'America/Blanc-Sablon',
    'America/Toronto',
    'America/Nipigon',
    'America/Thunder_Bay',
    'America/Iqaluit',
    'America/Pangnirtung',
    'America/Atikokan',
    'America/Winnipeg',
    'America/Rainy_River',
    'America/Resolute',
    'America/Rankin_Inlet',
    'America/Regina',
    'America/Swift_Current',
    'America/Edmonton',
    'America/Cambridge_Bay',
    'America/Yellowknife',
    'America/Inuvik',
    'America/Creston',
    'America/Dawson_Creek',
    'America/Fort_Nelson',
    'America/Vancouver',
    'America/Whitehorse',
    'America/Dawson',
    'Indian/Cocos',
    'Europe/Zurich',
    'Africa/Abidjan',
    'Pacific/Rarotonga',
    'America/Santiago',
    'America/Punta_Arenas',
    'Pacific/Easter',
    'Asia/Shanghai',
    'Asia/Urumqi',
    'America/Bogota',
    'America/Costa_Rica',
    'America/Havana',
    'Atlantic/Cape_Verde',
    'America/Curacao',
    'Indian/Christmas',
    'Asia/Nicosia',
    'Asia/Famagusta',
    'Europe/Prague',
    'Europe/Berlin',
    'Europe/Copenhagen',
    'America/Santo_Domingo',
    'Africa/Algiers',
    'America/Guayaquil',
    'Pacific/Galapagos',
    'Europe/Tallinn',
    'Africa/Cairo',
    'Africa/El_Aaiun',
    'Europe/Madrid',
    'Africa/Ceuta',
    'Atlantic/Canary',
    'Europe/Helsinki',
    'Pacific/Fiji',
    'Atlantic/Stanley',
    'Pacific/Chuuk',
    'Pacific/Pohnpei',
    'Pacific/Kosrae',
    'Atlantic/Faroe',
    'Europe/Paris',
    'Europe/London',
    'Asia/Tbilisi',
    'America/Cayenne',
    'Africa/Accra',
    'Europe/Gibraltar',
    'America/Godthab',
    'America/Danmarkshavn',
    'America/Scoresbysund',
    'America/Thule',
    'Europe/Athens',
    'Atlantic/South_Georgia',
    'America/Guatemala',
    'Pacific/Guam',
    'Africa/Bissau',
    'America/Guyana',
    'Asia/Hong_Kong',
    'America/Tegucigalpa',
    'America/Port-au-Prince',
    'Europe/Budapest',
    'Asia/Jakarta',
    'Asia/Pontianak',
    'Asia/Makassar',
    'Asia/Jayapura',
    'Europe/Dublin',
    'Asia/Jerusalem',
    'Asia/Kolkata',
    'Indian/Chagos',
    'Asia/Baghdad',
    'Asia/Tehran',
    'Atlantic/Reykjavik',
    'Europe/Rome',
    'America/Jamaica',
    'Asia/Amman',
    'Asia/Tokyo',
    'Africa/Nairobi',
    'Asia/Bishkek',
    'Pacific/Tarawa',
    'Pacific/Enderbury',
    'Pacific/Kiritimati',
    'Asia/Pyongyang',
    'Asia/Seoul',
    'Asia/Almaty',
    'Asia/Qyzylorda',
    'Asia/Qostanay', 
    'Asia/Aqtobe',
    'Asia/Aqtau',
    'Asia/Atyrau',
    'Asia/Oral',
    'Asia/Beirut',
    'Asia/Colombo',
    'Africa/Monrovia',
    'Europe/Vilnius',
    'Europe/Luxembourg',
    'Europe/Riga',
    'Africa/Tripoli',
    'Africa/Casablanca',
    'Europe/Monaco',
    'Europe/Chisinau',
    'Pacific/Majuro',
    'Pacific/Kwajalein',
    'Asia/Yangon',
    'Asia/Ulaanbaatar',
    'Asia/Hovd',
    'Asia/Choibalsan',
    'Asia/Macau',
    'America/Martinique',
    'Europe/Malta',
    'Indian/Mauritius',
    'Indian/Maldives',
    'America/Mexico_City',
    'America/Cancun',
    'America/Merida',
    'America/Monterrey',
    'America/Matamoros',
    'America/Mazatlan',
    'America/Chihuahua',
    'America/Ojinaga',
    'America/Hermosillo',
    'America/Tijuana',
    'America/Bahia_Banderas',
    'Asia/Kuala_Lumpur',
    'Asia/Kuching',
    'Africa/Maputo',
    'Africa/Windhoek',
    'Pacific/Noumea',
    'Pacific/Norfolk',
    'Africa/Lagos',
    'America/Managua',
    'Europe/Amsterdam',
    'Europe/Oslo',
    'Asia/Kathmandu',
    'Pacific/Nauru',
    'Pacific/Niue',
    'Pacific/Auckland',
    'Pacific/Chatham',
    'America/Panama',
    'America/Lima',
    'Pacific/Tahiti',
    'Pacific/Marquesas',
    'Pacific/Gambier',
    'Pacific/Port_Moresby',
    'Pacific/Bougainville',
    'Asia/Manila',
    'Asia/Karachi',
    'Europe/Warsaw',
    'America/Miquelon',
    'Pacific/Pitcairn',
    'America/Puerto_Rico',
    'Asia/Gaza',
    'Asia/Hebron',
    'Europe/Lisbon',
    'Atlantic/Madeira',
    'Atlantic/Azores',
    'Pacific/Palau',
    'America/Asuncion',
    'Asia/Qatar',
    'Indian/Reunion',
    'Europe/Bucharest',
    'Europe/Belgrade',
    'Europe/Kaliningrad',
    'Europe/Moscow',
    'Europe/Simferopol',
    'Europe/Kirov',
    'Europe/Astrakhan',
    'Europe/Volgograd',
    'Europe/Saratov',
    'Europe/Ulyanovsk',
    'Europe/Samara',
    'Asia/Yekaterinburg',
    'Asia/Omsk',
    'Asia/Novosibirsk',
    'Asia/Barnaul',
    'Asia/Tomsk',
    'Asia/Novokuznetsk',
    'Asia/Krasnoyarsk',
    'Asia/Irkutsk',
    'Asia/Chita',
    'Asia/Yakutsk',
    'Asia/Khandyga',
    'Asia/Vladivostok',
    'Asia/Ust-Nera',
    'Asia/Magadan',
    'Asia/Sakhalin',
    'Asia/Srednekolymsk',
    'Asia/Kamchatka',
    'Asia/Anadyr',
    'Asia/Riyadh',
    'Pacific/Guadalcanal',
    'Indian/Mahe',
    'Africa/Khartoum',
    'Europe/Stockholm',
    'Asia/Singapore',
    'America/Paramaribo',
    'Africa/Juba',
    'Africa/Sao_Tome',
    'America/El_Salvador',
    'Asia/Damascus',
    'America/Grand_Turk',
    'Africa/Ndjamena',
    'Indian/Kerguelen',
    'Asia/Bangkok',
    'Asia/Dushanbe',
    'Pacific/Fakaofo',
    'Asia/Dili',
    'Asia/Ashgabat',
    'Africa/Tunis',
    'Pacific/Tongatapu',
    'Europe/Istanbul',
    'America/Port_of_Spain',
    'Pacific/Funafuti',
    'Asia/Taipei',
    'Europe/Kiev',
    'Europe/Uzhgorod',
    'Europe/Zaporozhye',
    'Pacific/Wake',
    'America/New_York',
    'America/Detroit',
    'America/Kentucky/Louisville',
    'America/Kentucky/Monticello',
    'America/Indiana/Indianapolis',
    'America/Indiana/Vincennes',
    'America/Indiana/Winamac',
    'America/Indiana/Marengo',
    'America/Indiana/Petersburg',
    'America/Indiana/Vevay',
    'America/Chicago',
    'America/Indiana/Tell_City',
    'America/Indiana/Knox',
    'America/Menominee',
    'America/North_Dakota/Center',
    'America/North_Dakota/New_Salem',
    'America/North_Dakota/Beulah',
    'America/Denver',
    'America/Boise',
    'America/Phoenix',
    'America/Los_Angeles',
    'America/Anchorage',
    'America/Juneau',
    'America/Sitka',
    'America/Metlakatla',
    'America/Yakutat',
    'America/Nome',
    'America/Adak',
    'Pacific/Honolulu',
    'America/Montevideo',
    'Asia/Samarkand',
    'Asia/Tashkent',
    'America/Caracas',
    'Asia/Ho_Chi_Minh',
    'Pacific/Efate',
    'Pacific/Wallis',
    'Pacific/Apia',
    'Africa/Johannesburg'
];
Мати Гойра
источник
8
Это должно быть наверху
Евгений
За исключением того, что имейте в виду, что это не работает в некоторых браузерах. Например. IE11.
Пол ЛеБо
Ошибка в консоли IE: значение параметра «AMERICA / NEW_YORK» для «timeZone» находится вне допустимого диапазона. Ожидаемый: [ 'UTC'] @OloghoCyrilPaul
Matee Годжр
1
Очень легко, очень элегантно. Вы можете найти здесь список всех часовых поясов stackoverflow.com/questions/38399465/… . Для UTC выберите лондонский часовой пояс.
EPurpl3
1
Ни одно из этих значений не является «часовыми поясами», они представляют собой репрезентативные местоположения базы данных часовых поясов IANA для мест с одинаковыми историческими местными часовыми поясами и изменениями летнего времени.
RobG
28

Я не верю, что это возможно - нет возможности установить часовой пояс для объекта Date после его создания.

И в некотором смысле это имеет смысл - концептуально (если, возможно, не в реализации); за http://en.wikipedia.org/wiki/Unix_timestamp (выделено мной):

Время Unix, или время POSIX, представляет собой систему для описания моментов во времени, определяемых как количество секунд, прошедших с полуночного координированного универсального времени (UTC) четверга, 1 января 1970 года.

После того, как вы его построите, он будет представлять определенную точку в «реальном» времени. Часовой пояс имеет значение только тогда, когда вы хотите преобразовать эту абстрактную точку времени в удобочитаемую строку.

Таким образом, имеет смысл, что вы сможете изменить только фактическое время, которое Date представляет в конструкторе. К сожалению, кажется, что нет никакого способа передать в явном часовом поясе - и конструктор, который вы вызываете (возможно, правильно), переводит ваши «локальные» переменные времени в GMT, когда он канонически сохраняет их - поэтому нет никакого способа использоватьint, int, int конструктор для Время по Гринвичу

С другой стороны, тривиально просто использовать конструктор, который принимает String. Вам даже не нужно конвертировать числовой месяц в строку (по крайней мере в Firefox), поэтому я надеялся, что наивная реализация сработает. Тем не менее, после его тестирования он успешно работает в Firefox, Chrome и Opera, но не работает в Konqueror («Неверная дата»), Safari («Неверная дата») и IE («NaN»). Я полагаю, у вас просто есть массив поиска для преобразования месяца в строку, например так:

var months = [ '', 'January', 'February', ..., 'December'];

function createGMTDate(xiYear, xiMonth, xiDate) {
   return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT');
}
Анджей Дойл
источник
6
Если нет способа «установить часовой пояс для объекта Date после его создания», подразумеваете ли вы, что есть способ установить часовой пояс для объекта Date при его создании? Это не похоже на то, что js date - «тонкая обертка вокруг количества секунд с начала эпохи» - похоже, это число секунд плюс часовой пояс.
Энтони
1
@Anthony, он может использовать только часовой пояс клиента. Javascript может делать локальные для utc и обратно, но нет доступа к базе данных часовых поясов. Например, он не может сказать вам время в Мехико, когда вы находитесь в Сан-Диего.
Самуэль Даниэльсон,
20

Я знаю, что это старый, но если это поможет, вы можете использовать момент и часовой пояс. Если вы не видели их, посмотрите.

http://momentjs.com/timezone/

http://momentjs.com/

две действительно удобные библиотеки манипулирования временем.

ChewOnThis_Trident
источник
16

Если вы хотите решить немного другую, но связанную проблему создания объекта Javascript Date из года, месяца, дня, ..., включая часовой пояс - то есть, если вы хотите проанализировать строку в Date - тогда вы по-видимому, надо сделать невероятно сложный танец

// parseISO8601String : string -> Date
// Parse an ISO-8601 date, including possible timezone,
// into a Javascript Date object.
//
// Test strings: parseISO8601String(x).toISOString()
// "2013-01-31T12:34"              -> "2013-01-31T12:34:00.000Z"
// "2013-01-31T12:34:56"           -> "2013-01-31T12:34:56.000Z"
// "2013-01-31T12:34:56.78"        -> "2013-01-31T12:34:56.780Z"
// "2013-01-31T12:34:56.78+0100"   -> "2013-01-31T11:34:56.780Z"
// "2013-01-31T12:34:56.78+0530"   -> "2013-01-31T07:04:56.780Z"
// "2013-01-31T12:34:56.78-0330"   -> "2013-01-31T16:04:56.780Z"
// "2013-01-31T12:34:56-0330"      -> "2013-01-31T16:04:56.000Z"
// "2013-01-31T12:34:56Z"          -> "2013-01-31T12:34:56.000Z"
function parseISO8601String(dateString) {
    var timebits = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})(?::([0-9]*)(\.[0-9]*)?)?(?:([+-])([0-9]{2})([0-9]{2}))?/;
    var m = timebits.exec(dateString);
    var resultDate;
    if (m) {
        var utcdate = Date.UTC(parseInt(m[1]),
                               parseInt(m[2])-1, // months are zero-offset (!)
                               parseInt(m[3]),
                               parseInt(m[4]), parseInt(m[5]), // hh:mm
                               (m[6] && parseInt(m[6]) || 0),  // optional seconds
                               (m[7] && parseFloat(m[7])*1000) || 0); // optional fraction
        // utcdate is milliseconds since the epoch
        if (m[9] && m[10]) {
            var offsetMinutes = parseInt(m[9]) * 60 + parseInt(m[10]);
            utcdate += (m[8] === '+' ? -1 : +1) * offsetMinutes * 60000;
        }
        resultDate = new Date(utcdate);
    } else {
        resultDate = null;
    }
    return resultDate;
}

Таким образом, вы создаете «время UTC», используя дату без часового пояса (так что вы знаете, в каком он находится, а именно «локаль» UTC, а не локальное по умолчанию), а затем вручную применяете указанное смещение часового пояса.

Разве не было бы хорошо, если бы кто-то на самом деле думал об объекте даты Javascript более пяти минут ...

Норман грей
источник
1
спасибо за отличную функцию! единственное, что я хотел бы изменить, это добавить поддержку двоеточия в смещении часового пояса. var timebits = / ^ ([0-9] {4}) - ([0-9] {2}) - ([0-9] {2}) T ([0-9] {2}) :( [0-9] {2}) (:: ([0-9] *?)) (\ [0-9]. *)? (?: ([+ -]) ([0-9] { 2} [:]??) ([0-9] {2})) /;
Робнардо
2
Они думали об этом; к сожалению, «они» были разработчиками языка Java, поскольку JS просто скопировал класс Date Java для его первоначальной реализации.
Ксантир
@ Xanthir Ооо, ты прав, и я забыл, насколько ужасен был оригинальный объект Java Date; но, по крайней мере, Java устарела и пошла дальше, что Javascript, похоже, не в состоянии сделать (это странный язык, Javascript: довольно симпатичный, и не такой ужасный, как кажется на первый взгляд).
Норман Грей,
13
d = new Date();
utc = d.getTime() + (d.getTimezoneOffset() * 60000);
nd = new Date(utc + (3600000*offset));

offset value base on which location time zone you would like to set 
For India offset value +5.5,
New York offset value -4,
London offset value +1

для всех смещений местоположения Wiki Список смещений времени UTC

Виджай Латия
источник
Как это помогает Нью-Йорку в летнее время?
frederj
Для Нью-Йорка, пожалуйста, используйте значение смещения -4
Виджай Латия
1
Смещение для Нью-Йорка зависит от летнего времени. Иногда это -4, а иногда -5 en.wikipedia.org/wiki/Eastern_Time_Zone
frederj
8

getTimeZoneOffset является минусом для UTC + z.

var d = new Date(xiYear, xiMonth, xiDate);
if(d.getTimezoneOffset() > 0){
    d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
}
rinjan
источник
1
Небольшая ошибка,! = 0, а не> 0. Я закончил тем, что использовал это
Cristi Băluță
8

Это может помочь кому-то, поставить UTC в конце того, что вы передаете новому конструктору

По крайней мере в хроме можно сказать var date = new Date("2014-01-01 11:00:00 UTC")

Дрю ЛеСюр
источник
1
Возвращает «
Неверную
1
Замените `UTC` на +0000(заметил, что пробел между 00 и UTC необходимо удалить), и это будет работать как в Firefox, так и в Chrome. Хотя не уверен в Safari. (Ссылка: stackoverflow.com/a/17545854/1273587 )
cytsunny
8

Одноканальное решение

new Date(new Date(1422524805305).getTime() - 330*60*1000)

Вместо 1422524805305 используйте метку времени в миллисекундах. Вместо 330 используйте смещение часового пояса в минутах. GMT (например, Индия +5: 30 - 5 * 60 + 30 = 330 минут)

Vinay Vemula
источник
4
Это будет код, запускаемый на клиенте, а это означает, что часовой пояс будет отличаться для ваших пользователей, находящихся по-разному. Это решение потребует, чтобы все, кто в нем нуждался, жили в одном и том же часовом поясе (вашем).
Кевин Бил
@Kevin Beal в этом случае просто используйте getTimezoneOffset
maximus
6
// My clock 2018-07-25, 00:26:00 (GMT+7)
let date = new Date(); // 2018-07-24:17:26:00 (Look like GMT+0)
const myTimeZone = 7; // my timeZone 
// my timeZone = 7h = 7 * 60 * 60 * 1000 (millisecond);
// 2018-07-24:17:26:00 = x (milliseconds)
// finally, time in milliseconds (GMT+7) = x + myTimezone 
date.setTime( date.getTime() + myTimeZone * 60 * 60 * 1000 );
// date.toISOString() = 2018-07-25, 00:26:00 (GMT+7)
Туан Нгуен
источник
Объяснение вашего кода и того, как он решает проблему, повысит качество вашего ответа и поможет обучению пользователей.
Nic3500
5

Самый простой способ найти правильную дату - использовать datejs.

http://www.datejs.com/

Я получаю свои даты через Ajax в следующем формате: «2016-01-12T00: 00: 00»

var yourDateString = '2016-01-12T00:00:00';
var yourDate = new Date(yourDateString);
console.log(yourDate);
if (yourDate.getTimezoneOffset() > 0){
    yourDate = new Date(yourDateString).addMinutes(yourDate.getTimezoneOffset());
}
console.log(yourDate);

Консоль будет читать:

Пн Ян 11 2016 19:00:00 GMT-0500 (Восточное стандартное время)

Вт Янв 2016 2016 00:00:00 GMT-0500 (Восточное стандартное время)

https://jsfiddle.net/vp1ena7b/3/

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

Я думал, что это может кому-то помочь ...

Барри Франклин
источник
Перепробовал все методы, и это был единственный способ получить полночь, что было то, что я был после!
SharpC
3

любой пробег в

var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();
meouw
источник
Мне кажется, это помогает мне (в одном часовом поясе от GMT), но поскольку «локаль» не обязательно связана с часовым поясом, я бы не стал на это полагаться.
Wytze
3

Этот код вернет ваш объект Date, отформатированный в часовом поясе браузера .

Date.prototype.timezone = function () {
    this.setHours(this.getHours() + (new Date().getTimezoneOffset() / 60));
    return this;
}

Редактировать:

Чтобы не загрязнять Date API, указанную выше функцию можно преобразовать в служебную функцию. Функция принимает объект Date и возвращает видоизмененный объект Date.

function setTimeZone(date) {
    date.setHours(date.getHours() + (new Date().getTimezoneOffset() / 60));
    return date;
}
Марко Даль Зово
источник
6
Нет расширению нативных объектов
Пол Румкин
1

Лучшее решение, которое я видел из этого, пришло от

http://www.codingforums.com/archive/index.php/t-19663.html

Функция печати времени

<script language="javascript" type="text/javascript">
//borrowed from echoecho
//http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
workDate = new Date()
UTCDate = new Date()
UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)

function printTime(offset) {
    offset++;
    tempDate = new Date()
    tempDate.setTime(UTCDate.getTime()+3600000*(offset))
    timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
    timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
    timeValue += " hrs."
    return timeValue
    }
    var now = new Date()
    var seed = now.getTime() % 0xfffffff
    var same = rand(12)
</script>

Banff, Canada:
<script language="JavaScript">document.write(printTime("-7"))</script>

Пример полного кода

<html>

<head>
<script language="javascript" type="text/javascript">
//borrowed from echoecho
//http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
workDate = new Date()
UTCDate = new Date()
UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)

function printTime(offset) {
offset++;
tempDate = new Date()
tempDate.setTime(UTCDate.getTime()+3600000*(offset))
timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
timeValue += " hrs."
return timeValue
}
var now = new Date()
var seed = now.getTime() % 0xfffffff
var same = rand(12)
</script>

</head>

<body>
Banff, Canada:
<script language="JavaScript">document.write(printTime("-7"))</script>
<br>
Michigan:
<script language="JavaScript">document.write(printTime("-5"))</script>
<br>
Greenwich, England(UTC):
<script language="JavaScript">document.write(printTime("-0"))</script>
<br>
Tokyo, Japan:
<script language="JavaScript">document.write(printTime("+9"))</script>
<br>
Berlin, Germany:
<script language="JavaScript">document.write(printTime("+1"))</script>

</body>
</html>
Джеффри Л. Робертс
источник
Ваш пример исключает переход на летнее время. Текущее время: пятница, 04 октября 2013 г., 11:13:43 GMT-0700 (тихоокеанское летнее время) Время: пятница, 04 октября 2013 г., 18:13:43 GMT Банф, Канада: 1213 часов. Мичиган: 1413 часов Гринвич, Англия (UTC): 1913 Токио, Япония: 0413 часов Берлин, Германия: 2013 г.
Джесон Мартаджая
0

Если вы хотите проверить разницу во времени между двумя датами, вы можете просто проверить, является ли второй часовой пояс меньшим или большим по сравнению с вашим первым желаемым часовым поясом, и вычесть или добавить время.

  const currTimezone = new Date().getTimezoneOffset(); // your timezone
  const newDateTimezone = date.getTimezoneOffset(); // date with unknown timezone

  if (currTimezone !== newDateTimezone) {
    // and below you are checking if difference should be - or +. It depends on if unknown timezone is lesser or greater than yours
    const newTimezone = (currTimezone - newDateTimezone) * (currTimezone > newDateTimezone ? 1 : -1);
    date.setTime(date.getTime() + (newTimezone * 60 * 1000));
  }
Piosek
источник
0

GMT -03: 00 Пример

new Date(new Date()-3600*1000*3).toISOString();  // 2020-02-27T15:03:26.261Z

Или даже

now  = new Date().getTime()-3600*1000*3; // 1582818380528
data = new Date(now).toISOString();      // 2020-02-27T15:03:26.261Z
Рафаэль Ксавье
источник
-1

Это сработало для меня. Не уверен, что это хорошая идея.

var myDate = new Date();
console.log('myDate:', myDate);   // myDate: "2018-04-04T01:09:38.112Z"

var offset = '+5';  // e.g. if the timeZone is -5

var MyDateWithOffset = new Date( myDate.toGMTString() + offset );   

console.log('MyDateWithOffset:', MyDateWithOffset); // myDateWithOffset: "2018-04-03T20:09:38.000Z"

ofmoreno06
источник
-1

Я использовал пакет timezone-js.

var timezoneJS  = require('timezone-js');
var tzdata = require('tzdata');

createDate(dateObj) {
    if ( dateObj == null ) {
        return null;
    }
    var nativeTimezoneOffset = new Date().getTimezoneOffset();
    var offset = this.getTimeZoneOffset();

    // use the native Date object if the timezone matches
    if ( offset == -1 * nativeTimezoneOffset ) {
        return dateObj;
    }

    this.loadTimeZones();

    // FIXME: it would be better if timezoneJS.Date was an instanceof of Date
    //        tried jquery $.extend
    //        added hack to Fiterpickr to look for Dater.getTime instead of "d instanceof Date"
    return new timezoneJS.Date(dateObj,this.getTimeZoneName());
},
Стивен Инс
источник
-11

Это лучшее решение

С помощью:

// TO ALL dates
Date.timezoneOffset(-240) // +4 UTC

// Override offset only for THIS date
new Date().timezoneOffset(-180) // +3 UTC

Код:

Date.prototype.timezoneOffset = new Date().getTimezoneOffset();

Date.setTimezoneOffset = function(timezoneOffset) {
  return this.prototype.timezoneOffset = timezoneOffset;
};

Date.getTimezoneOffset = function() {
  return this.prototype.timezoneOffset;
};

Date.prototype.setTimezoneOffset = function(timezoneOffset) {
  return this.timezoneOffset = timezoneOffset;
};

Date.prototype.getTimezoneOffset = function() {
  return this.timezoneOffset;
};

Date.prototype.toString = function() {
  var offsetDate, offsetTime;
  offsetTime = this.timezoneOffset * 60 * 1000;
  offsetDate = new Date(this.getTime() - offsetTime);
  return offsetDate.toUTCString();
};

['Milliseconds', 'Seconds', 'Minutes', 'Hours', 'Date', 'Month', 'FullYear', 'Year', 'Day'].forEach((function(_this) {
  return function(key) {
    Date.prototype["get" + key] = function() {
      var offsetDate, offsetTime;
      offsetTime = this.timezoneOffset * 60 * 1000;
      offsetDate = new Date(this.getTime() - offsetTime);
      return offsetDate["getUTC" + key]();
    };
    return Date.prototype["set" + key] = function(value) {
      var offsetDate, offsetTime, time;
      offsetTime = this.timezoneOffset * 60 * 1000;
      offsetDate = new Date(this.getTime() - offsetTime);
      offsetDate["setUTC" + key](value);
      time = offsetDate.getTime() + offsetTime;
      this.setTime(time);
      return time;
    };
  };
})(this));

Кофейная версия:

Date.prototype.timezoneOffset = new Date().getTimezoneOffset()


Date.setTimezoneOffset = (timezoneOffset)->
    return @prototype.timezoneOffset = timezoneOffset


Date.getTimezoneOffset = ->
    return @prototype.timezoneOffset


Date.prototype.setTimezoneOffset = (timezoneOffset)->
    return @timezoneOffset = timezoneOffset


Date.prototype.getTimezoneOffset = ->
    return @timezoneOffset


Date.prototype.toString = ->
    offsetTime = @timezoneOffset * 60 * 1000
    offsetDate = new Date(@getTime() - offsetTime)
    return offsetDate.toUTCString()


[
    'Milliseconds', 'Seconds', 'Minutes', 'Hours',
    'Date', 'Month', 'FullYear', 'Year', 'Day'
]
.forEach (key)=>
    Date.prototype["get#{key}"] = ->
        offsetTime = @timezoneOffset * 60 * 1000
        offsetDate = new Date(@getTime() - offsetTime)
        return offsetDate["getUTC#{key}"]()

    Date.prototype["set#{key}"] = (value)->
        offsetTime = @timezoneOffset * 60 * 1000
        offsetDate = new Date(@getTime() - offsetTime)
        offsetDate["setUTC#{key}"](value)
        time = offsetDate.getTime() + offsetTime
        @setTime(time)
        return time
Maxmaxmaximus
источник
2
Вау, мне это тоже не нравится, но я думаю, что люди действительно ненавидят тебя за то, что ты отвергаешь прототип встроенных объектов!
Джош из Карибу