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


412

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

new Date(xiYear, xiMonth, xiDate)

Вкажіть правильну дату, але він вважає, що ця дата - GMT + 01: 00 через літній час.

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

Прийнята відповідь вказувала мені в правильному напрямку, проте просто використання 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.


101
Синтаксис "Нова дата (Date.UTC (...))" дозволяє створити дату, еквівалентну даті UTC за часом, який вона представляє, але це не однаково - у неї є різний часовий пояс (не UTC).
Антоній

52
Майте на увазі, що при використанні "Дата" значення "місяць" має діапазон від 0-11 (а не 1-12). Я продовжував отримувати компенсацію часового поясу на 2 години (в той час як це повинно було бути 1 год), і мені знадобилося кілька годин, щоб з'ясувати, що причина - неправильний місяць.
Select0r

4
Ця відповідь чудова. Але я використовую бібліотеку [datepicker ui], яка використовує нову дату у багатьох місцях. Все, що я хочу, - це встановити часовий пояс UTC, і кожна дата відповідає новому часовому поясу. Я здивований, що у JavaScript немає для цього нічого.
Саньєєв Кумар Дангі

6
@ jishi - об’єкти дати базуються на значення часу UTC, а не на місцевому часі. Однак метод Date.prototype.toString за замовчуванням відображатиме локальні значення часу.
RobG

5
@ Ентоні - " але це не той самий час ", невірно. Він відображає рівно той самий момент у часі, єдиною різницею є зміщення часового поясу.
RobG

198
var d = new Date(xiYear, xiMonth, xiDate);
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );

Ця відповідь підібрана спеціально до оригінального питання, і не дасть відповіді, яку ви обов'язково очікуєте. Зокрема, деякі люди захочуть віднімати зміщення часового поясу, а не додавати його. Пам'ятайте, що вся суть цього рішення полягає в злому об'єкта дати JavaScript для певної деріаріалізації, а не в усіх випадках.


62
@gthmb звичайно, але я вважаю, що *60*1000в цьому випадку ясніше; Іншими словами, досить зрозуміло, чому саме там.
TWR Коул

22
Це майже працює для мене, за винятком того, що я маю використовувати - (мінус) замість + (плюс), щоб отримати потрібний час для мого часового поясу.
Wytze

3
Так, як зазначають інші - я думаю, що у цій відповіді є помилка. Повинен бути мінус не плюс.
UpTheCreek

3
Відповідно до developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… значення, повернене getTimezoneOffset, підписується відповідно до фактичного зміщення у вашій місцевості під час виклику функції, включаючи врахування DST, тому я не розумію, чому вам потрібно відняти це.
TWR Коул

15
Якщо ви додасте timezoneOffset до об’єкта дати, його значення у форматі в локальному часовому поясі буде схожим на правильне значення в UTC, але воно все одно матиме початкове зміщення часового поясу (а деякі представлення на зразок "ISOString" насправді показуватимуть це). Отже, залежно від того, як ви потім серіалізуєте об’єкт дати, JS може застосувати зсув часового поясу знову , даючи неправильну відповідь. Я вважаю, що це є причиною плутанини в цих коментарях між +/-. У будь-якому разі, моя суть є за цей факт, а також за те, що "в більшості випадків ви отримуєте те, що очікуєте".
метамат

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()); 
}

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 Gojra

1
Дуже легко, дуже елегантно. Тут ви можете знайти список із усіма часовими поясами stackoverflow.com/questions/38399465/… . Для UTC виберіть часовий пояс Лондона.
EPurpl3

1
Жодне з цих значень не є "часовими поясами", вони є репрезентативними місцями баз даних часових поясів IANA для місць, які мають однакові історичні місцеві часові зони та зміни літнього часу.
RobG

28

Я не вірю, що це можливо - немає можливості встановити часовий пояс на об'єкт Date після його створення.

І певним чином це має сенс - концептуально (якщо можливо, не в реалізації); на http://en.wikipedia.org/wiki/Unix_timestamp (моє наголос):

Час Unix, або час POSIX, - це система опису моментів у часі, що визначається як кількість секунд, що минули з півночі, координованого універсальним часом (UTC) четверга, 1 січня 1970 року.

Після того як ви побудували його, він буде представляти певний момент у "реальному" часі. Часовий пояс є актуальним лише тоді, коли ви хочете перетворити цю абстрактну часову точку в зрозумілий для людини рядок.

Таким чином, є сенс, що ви зможете змінити фактичний час, який дата представляє в конструкторі. На жаль, здається, що немає можливості пройти через явний часовий пояс - і конструктор, якого ви викликаєте (можливо, правильно), переводить ваші "локальні" змінні часу в GMT, коли він зберігає їх канонічно - тому немає можливості використовувати int, int, intконструктор для GMT раз.

З іншого боку, неважливо просто використовувати конструктор, який замість нього використовує String. Вам навіть не потрібно перетворювати числовий місяць у 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
Якщо немає способу "встановити часовий пояс на об'єкт дати після його створення", ви маєте на увазі, що існує спосіб встановити часовий пояс на об'єкт "Дата" під час його створення? Не схоже, що дата js - це "тонка обгортка протягом декількох секунд з епохи" - схоже, що це кількість секунд плюс часовий пояс.
Антоній

1
@Anthony, Він може використовувати лише часовий пояс клієнта. Javascript може робити локальний утч і назад, але немає доступу до бази даних часових поясів. Наприклад, він не може сказати тобі час у Мехіко, коли ти в Сан-Дієго.
Самуель Даніельсон

20

Я знаю, що це старе, але якщо це допоможе, ви можете використовувати часовий пояс моменту та моменту. Якщо ви їх не бачили, подивіться.

http://momentjs.com/timezone/

http://momentjs.com/

дві справді зручні бібліотеки для маніпулювання часом.


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}))? /;
robnardo

2
Вони думали про це; на жаль, "вони" були дизайнерами мови Java, оскільки JS просто скопіював клас Date на Java для її початкової реалізації.
Ксантір

@Xanthir Oooh, ти маєш рацію, і я забув, наскільки жахливим був оригінальний об'єкт 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

для всіх зміщених місць у Вікі-списку зсувів часу UTC


Як це допомагає Нью-Йорку в літній час?
frederj

Для Нью-Йорка використовуйте значення зміщення -4
Vijay Lathiya

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 );
}

1
Маленька помилка
,!

8

Це може допомогти комусь, поставте UTC наприкінці того, що ви передаєте новому конструктору

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


1
Повертається "Недійсна дата" на Safari
pmrotule

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 використовуйте зміщення часового поясу в хвилинах wrt. GMT (наприклад, Індія +5: 30 - це 5 * 60 + 30 = 330 хвилин)


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 (східний стандартний час)

Чт 12 січня 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();

Це, здається, робить для мене хитрість (один часовий пояс від GMT), але оскільки "locale" не обов'язково пов'язаний з часовим поясом, я б не покладався на нього.
Wytze

3

Цей код поверне ваш об'єкт Date у форматі часового поясу браузера .

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

Редагувати:

Щоб уникнути забруднення API 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>

Ваш приклад виключає літній час. CurrentTime: Пт. 04 жовтня 2013, 11:13:43 GMT-0700 (Тихоокеанський літній час) UtcTime: Пт, 04 жовтня 2013 18:13:43 GMT Банфф, Канада: 1213 год. Мічиган: 1413 год. Грінвіч, Англія (UTC): 1913 год. Токіо, Японія: 0413 год. Берлін, Німеччина: 2013 год.
Jeson Martajaya

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));
  }

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"


-1

Я використовував пакет time-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

2
Вау, мені це теж не подобається, але я думаю, що люди насправді ненавидять вас, перевершуючи прототип вбудованих!
Джош з Карібу
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.