Buat Tanggal dengan zona waktu yang ditetapkan tanpa menggunakan representasi string

412

Saya memiliki halaman web dengan tiga dropdown untuk hari, bulan, dan tahun. Jika saya menggunakan Datekonstruktor JavaScript yang mengambil angka, maka saya mendapatkan Dateobjek untuk zona waktu saya saat ini:

new Date(xiYear, xiMonth, xiDate)

Berikan tanggal yang benar, tetapi menurutnya tanggal tersebut GMT + 01: 00 karena waktu musim panas.

Masalahnya di sini adalah bahwa saya kemudian meneruskan ini Dateke metode Ajax dan ketika tanggal deserialised di server itu telah dikonversi ke GMT dan kehilangan satu jam yang bergerak kembali satu hari. Sekarang saya bisa melewatkan hari, bulan, dan tahun secara individual ke dalam metode Ajax, tetapi tampaknya harus ada cara yang lebih baik.

Jawaban yang diterima mengarahkan saya ke arah yang benar, namun hanya setUTCHours()dengan menggunakan itu sendiri berubah:

Apr 5th 00:00 GMT+01:00 

untuk

Apr 4th 23:00 GMT+01:00

Saya kemudian juga harus mengatur tanggal UTC, bulan dan tahun untuk berakhir dengan

Apr 5th 01:00 GMT+01:00

itulah yang saya inginkan.

Dan
sumber
9
Jika jawaban yang diterima mengarahkan Anda ke arah yang benar tetapi tidak menjawab pertanyaan Anda, saya berpendapat itu bukan jawaban yang diterima. Jawabannya harus menjawab pertanyaan yang diajukan.
TWR Cole

Jawaban:

481

menggunakannya .setUTCHours()adalah mungkin untuk benar-benar mengatur tanggal dalam waktu UTC, yang memungkinkan Anda untuk menggunakan waktu UTC di seluruh sistem.

Anda tidak dapat mengaturnya menggunakan UTC di konstruktor, kecuali Anda menentukan string tanggal.

Menggunakan new Date(Date.UTC(year, month, day, hour, minute, second))Anda dapat membuat objek-Tanggal dari waktu UTC tertentu.

jishi
sumber
101
Sintaks "Date baru (Date.UTC (...))" memungkinkan Anda membuat tanggal yang setara dengan tanggal UTC dalam hal titik waktu yang diwakilinya, tetapi tidak sama - memiliki zona waktu berbeda (bukan UTC).
Anthony
52
Perlu diingat bahwa ketika menggunakan "Tanggal", "bulan" -nilai memiliki rentang 0-11 (bukan 1-12). Saya terus mendapatkan offset zona waktu 2 jam (padahal seharusnya 1 jam) dan saya butuh waktu berjam-jam untuk mengetahui bahwa alasannya adalah bulan yang salah.
Pilih0r
4
Jawaban ini bagus. Tetapi saya menggunakan perpustakaan [datepicker ui] yang menggunakan Date baru di banyak tempat. Yang saya inginkan adalah mengatur zona waktu UTC dan setiap tanggal sesuai zona waktu baru. Saya terkejut Javascript tidak memiliki apa-apa untuk ini.
Sanjeev Kumar Dangi
6
@ jishi — Objek tanggal didasarkan pada nilai waktu UTC, bukan waktu lokal. Namun, metode Date.prototype.toString default akan menampilkan nilai waktu lokal.
RobG
5
@ Anthony— " tapi ini bukan waktu yang sama " tidak benar. Ini mewakili momen yang persis sama dalam waktu, satu-satunya perbedaan adalah offset zona waktu.
RobG
199
var d = new Date(xiYear, xiMonth, xiDate);
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );

Jawaban ini dirancang khusus untuk pertanyaan awal, dan tidak akan memberikan jawaban yang Anda harapkan. Secara khusus, beberapa orang ingin mengurangi offset zona waktu alih-alih menambahkannya. Ingat juga bahwa inti dari solusi ini adalah untuk meretas objek tanggal javascript untuk deserialisasi tertentu, tidak untuk menjadi benar dalam semua kasus.

TWR Cole
sumber
62
@ gthmb tentu saja, tapi saya merasa *60*1000lebih jelas dalam hal ini; dengan kata lain, cukup jelas mengapa itu ada.
TWR Cole
22
Ini hampir berfungsi untuk saya, kecuali saya harus menggunakan - (minus) daripada + (plus) untuk mendapatkan waktu yang tepat untuk zona waktu saya.
Wytze
3
Ya, seperti yang ditunjukkan orang lain - saya pikir ada kesalahan dalam jawaban ini. Harus dikurangi bukan ditambah.
UpTheCreek
3
Menurut developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… nilai yang dikembalikan oleh getTimezoneOffset ditandatangani sesuai dengan offset aktual di lokal Anda pada saat Anda memanggil fungsi, termasuk memperhitungkan DST, jadi saya tidak mengerti mengapa Anda harus mengurangi itu.
TWR Cole
15
Jika Anda menambahkan timezoneOffset ke objek tanggal, nilainya seperti yang diformat dalam zona waktu lokal akan terlihat seperti nilai yang benar di UTC, tetapi masih memiliki offset zona waktu asli (dan beberapa representasi seperti "ISOString" akan benar-benar menunjukkannya). Jadi, tergantung pada bagaimana Anda meng-serialkan objek tanggal, JS mungkin menerapkan zona waktu kembali , memberikan Anda jawaban yang salah. Saya percaya ini bertanggung jawab atas kebingungan dalam komentar ini antara +/-. Bagaimanapun, downvote saya adalah untuk fakta ini dan juga untuk "dalam banyak kasus Anda mendapatkan apa yang Anda harapkan".
metamatt
173

Saya yakin Anda memerlukan fungsi createDateAsUTC (bandingkan dengan 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
sumber
36
Saya kagum dengan kejelasan dan bantuannya jawabannya. Tidak tahu bahwa bekerja dengan tanggal Javascript adalah mimpi buruk sampai hari ini: S
will824
Pikiran menjelaskan perbedaan antara keduanya? Yang pertama dikonversi datemenjadi zona waktu UTC, tetapi yang kedua tampaknya tidak berguna? (mengembalikan tanggal yang sama dengan date)
Jonathan Lin
4
Saya mengerti sekarang: Yang pertama mengembalikan tanggal di zona waktu UTC, dengan nilai tanggal literal waktu setempat. Yang kedua mengembalikan tanggal di zona waktu lokal, tetapi dengan nilai tanggal literal UTC.
Jonathan Lin
8
Pendekatan ini adalah salah satu implementasi dari pola yang disebut "pergeseran zaman", yang dimaksudkan untuk memindahkan zaman (yang berbasis UTC) ke yang berubah oleh offset zona waktu saat ini. Sayangnya, meskipun hal ini biasa dilihat, pendekatan ini cacat. DateObjek JavaScript akan selalu mencerminkan zaman unix berbasis UTC, dan zona waktu lokal . Gejala ini terlihat saat Anda memanggil toStringobjek tanggal yang dihasilkan dan masih melihat zona waktu setempat, meskipun Anda mengharapkannya berada di UTC.
Matt Johnson-Pint
2
Itu juga dapat menyebabkan kesalahan dalam nilai waktu, dekat transisi waktu musim panas dari zona waktu lokal. Singkatnya, pemindahan zaman (melalui implementasi apa pun) tidak berfungsi dengan Dateobjek JavaScript . Cara lain untuk melihatnya di sini adalah yang Date.UTCmengharapkan nilai berbasis UTC, dan Anda memberinya nilai waktu setempat, dan sebaliknya dengan Datekonstruktor.
Matt Johnson-Pint
70

Cukup Tetapkan Zona Waktu dan Dapatkan Kembali Menurut

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

Lainnya Time-zona adalah sebagai berikut

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'
];
Matee Gojra
sumber
8
Ini harus naik di bagian atas
Eugene
Kecuali perlu diketahui bahwa ini tidak berfungsi di beberapa browser. Misalnya. IE11.
Paul LeBeau
Kesalahan di Konsol IE: Nilai opsi 'AMERICA / NEW_YORK' untuk 'timeZone' berada di luar rentang yang valid. Diharapkan: ['UTC'] @OloghoCyrilPaul
Gojra
1
Sangat mudah, sangat elegan. Anda dapat menemukan di sini daftar dengan semua zona waktu stackoverflow.com/questions/38399465/… . Untuk UTC pilih zona waktu London.
EPurpl3
1
Tidak satu pun dari nilai-nilai itu adalah "zona waktu", mereka adalah lokasi perwakilan basis data zona waktu IANA untuk tempat-tempat yang memiliki perubahan zona waktu lokal dan perubahan waktu siang hari yang sama.
RobG
28

Saya tidak percaya ini mungkin - tidak ada kemampuan untuk mengatur zona waktu pada objek Tanggal setelah dibuat.

Dan dengan cara ini masuk akal - secara konseptual (jika mungkin tidak dalam implementasi); per http://en.wikipedia.org/wiki/Unix_timestamp (penekanan milik saya):

Waktu unix, atau waktu POSIX, adalah sistem untuk menggambarkan instans dalam waktu, yang didefinisikan sebagai jumlah detik yang berlalu sejak tengah malam Waktu Universal Terkoordinasi (UTC) pada Kamis, 1 Januari 1970.

Setelah Anda membuat satu, itu akan mewakili titik tertentu dalam waktu "nyata". Zona waktu hanya relevan ketika Anda ingin mengubah titik waktu abstrak itu menjadi string yang dapat dibaca manusia.

Dengan demikian masuk akal Anda hanya akan dapat mengubah waktu aktual yang diwakili oleh Tanggal dalam konstruktor. Sayangnya tampaknya tidak ada cara untuk lulus dalam zona waktu eksplisit - dan konstruktor yang Anda panggil (bisa dibilang benar) menerjemahkan variabel waktu "lokal" Anda ke dalam GMT ketika menyimpannya secara kanonik - jadi tidak ada cara untuk menggunakan int, int, intkonstruktor untuk Waktu GMT.

Di sisi positifnya, sepele untuk hanya menggunakan konstruktor yang mengambil String sebagai gantinya. Anda bahkan tidak perlu mengubah bulan angka menjadi String (setidaknya di Firefox), jadi saya berharap implementasi yang naif akan berhasil. Namun, setelah mencobanya berfungsi dengan sukses di Firefox, Chrome, dan Opera tetapi gagal di Konqueror ("Invalid Date"), Safari ("Invalid Date") dan IE ("NaN"). Saya kira Anda hanya memiliki array pencarian untuk mengkonversi bulan menjadi sebuah string, seperti:

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

function createGMTDate(xiYear, xiMonth, xiDate) {
   return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT');
}
Andrzej Doyle
sumber
6
Jika tidak ada cara untuk "mengatur zona waktu pada objek Tanggal setelah dibuat", apakah Anda menyiratkan bahwa ada cara untuk mengatur zona waktu pada objek Tanggal seperti yang dibuat? Sepertinya tanggal js adalah "pembungkus tipis di sekitar beberapa detik sejak Zaman" - sepertinya itu hitungan detik, ditambah zona waktu.
Anthony
1
@Anthony, Itu hanya bisa menggunakan zona waktu klien. Javascript dapat dilakukan secara lokal ke utc dan kembali tetapi tidak ada akses ke database zona waktu. Misalnya, tidak bisa memberi tahu Anda Waktu di Mexico City saat Anda berada di San Diego.
Samuel Danielson
20

Saya tahu ini sudah lama tetapi jika itu membantu Anda bisa menggunakan zona waktu momen dan momen. Jika Anda belum melihat mereka melihatnya.

http://momentjs.com/timezone/

http://momentjs.com/

dua perpustakaan manipulasi waktu yang sangat berguna.

ChewOnThis_Trident
sumber
16

Jika Anda ingin berurusan dengan masalah yang sedikit berbeda, tetapi terkait, membuat objek Tanggal Javascript dari tahun, bulan, hari, ..., termasuk zona waktu - yaitu, jika Anda ingin mengurai string menjadi Tanggal - maka Anda rupanya harus melakukan tarian yang sangat rumit:

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

Artinya, Anda membuat 'waktu UTC' menggunakan tanggal tanpa zona waktu (jadi Anda tahu di mana lokasi itu, yaitu 'lokal' UTC, dan tidak default ke yang lokal), lalu menerapkan secara manual zona waktu yang ditunjukkan.

Bukankah lebih baik jika seseorang benar-benar berpikir tentang objek tanggal Javascript selama lebih dari, oooh, lima menit ....

Norman Gray
sumber
1
terima kasih untuk fungsinya yang luar biasa! satu-satunya hal yang akan saya ubah adalah menambahkan dukungan untuk titik dua di zona waktu offset. 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
Mereka memang memikirkannya; Sayangnya, "mereka" adalah desainer bahasa Jawa, karena JS hanya menyalin kelas Tanggal Java untuk implementasi awalnya.
Xanthir
@Xanthir Oooh, Anda benar, dan saya lupa betapa buruknya objek Java Date yang asli; tapi setidaknya Java tidak lagi menggunakannya dan melanjutkan, sesuatu yang Javascript tampaknya tidak dapat lakukan (itu adalah bahasa yang aneh, Javascript: agak lucu, dan tidak terlalu mengerikan seperti yang terlihat pertama kali).
Norman Gray
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

untuk semua lokasi mengimbangi Daftar offset waktu Wiki UTC

Vijay Lathiya
sumber
Bagaimana ini membantu New York selama waktu Musim Panas?
frederj
Untuk New York, silakan gunakan nilai offset -4
Vijay Lathiya
1
Offset untuk New York bervariasi sesuai dengan waktu Musim Panas. Terkadang -4 dan terkadang -5 en.wikipedia.org/wiki/Eastern_Time_Zone
frederj
8

getTimeZoneOffset minus untuk UTC + z.

var d = new Date(xiYear, xiMonth, xiDate);
if(d.getTimezoneOffset() > 0){
    d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
}
rinjan
sumber
1
Sedikit kesalahan
,!
8

Ini dapat membantu seseorang, menempatkan UTC di akhir apa yang Anda berikan kepada konstruktor baru

Setidaknya di chrome bisa Anda katakan var date = new Date("2014-01-01 11:00:00 UTC")

Drew LeSueur
sumber
1
Mengembalikan "Tanggal Tidak Valid" di Safari
pmrotule
1
Ganti `UTC` dengan +0000(perhatikan bahwa ruang antara 00 dan UTC perlu dihapus) dan ini akan berfungsi pada Firefox dan Chrome. Tidak yakin untuk Safari. (Referensi: stackoverflow.com/a/17545854/1273587 )
cytsunny
8

Solusi satu baris

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

Alih-alih 1422524805305, gunakan cap waktu dalam milidetik Alih-alih 330, gunakan offset zona waktu Anda dalam hitungan menit. GMT (mis. India +5: 30 adalah 5 * 60 + 30 = 330 menit)

Vinay Vemula
sumber
4
Ini akan menjadi kode yang dijalankan pada klien, yang berarti zona waktu akan berbeda untuk pengguna yang berlokasi berbeda. Solusi ini akan mengharuskan setiap orang yang membutuhkannya hidup di zona waktu yang sama (milik Anda).
Kevin Beal
@Kevin Beal dalam hal ini cukup gunakan 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)
Tuan Nguyen
sumber
Menjelaskan kode Anda dan cara memecahkan masalah akan meningkatkan kualitas jawaban Anda, dan membantu mempelajari pengguna.
Nic3500
5

Cara termudah yang saya temukan untuk mendapatkan tanggal yang benar adalah menggunakan datejs.

http://www.datejs.com/

Saya mendapatkan tanggal saya melalui Ajax dalam format ini sebagai string: '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);

Konsol akan membaca:

Senin 11 Jan 2016 19:00:00 GMT-0500 (Waktu Standar Timur)

Sel 12 Jan 2016 00:00:00 GMT-0500 (Waktu Standar Timur)

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

The 'addMinutes' berasal dari datejs, Anda mungkin bisa melakukan ini di js murni sendiri, tetapi saya sudah punya datejs di proyek saya jadi saya menemukan cara untuk menggunakannya untuk mendapatkan tanggal yang benar.

Saya pikir ini mungkin membantu seseorang ...

Barry Franklin
sumber
Mencoba semua metode dan ini adalah satu-satunya untuk mendapatkan tengah malam yang saya cari!
SharpC
3

jarak tempuh apa pun di

var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();
meouw
sumber
Ini tampaknya melakukan trik untuk saya (satu zona waktu jauh dari GMT), tetapi karena "lokal" belum tentu terkait zona waktu, saya tidak akan bergantung padanya.
Wytze
3

Kode ini akan mengembalikan objek Tanggal Anda yang diformat dengan zona waktu browser .

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

Edit:

Untuk menghindari mencemari API Tanggal, fungsi di atas dapat diubah menjadi fungsi utilitas. Fungsi mengambil objek Date, dan mengembalikan objek Date bermutasi.

function setTimeZone(date) {
    date.setHours(date.getHours() + (new Date().getTimezoneOffset() / 60));
    return date;
}
Marco Dal Zovo
sumber
6
Tidak untuk memperluas objek asli
Paul Rumkin
1

Solusi terbaik yang saya lihat dari ini berasal dari

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

Fungsi Waktu Cetak

<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>

Contoh Kode Lengkap

<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>
Jeffrey L. Roberts
sumber
Contoh Anda tidak termasuk Waktu Musim Panas. CurrentTime: Jum 4 Okt 2013 11:13:43 GMT-0700 (Waktu Siang Pasifik) UtcTime: Jum, 04 Okt 2013 18:13:43 GMT Banff, Kanada: 1213 jam. Michigan: 1413 jam. Greenwich, Inggris (UTC): 1913 jam. Tokyo, Jepang: 0413 jam. Berlin, Jerman: 2013 jam.
Jeson Martajaya
0

jika Anda ingin memeriksa perbedaan dalam waktu antara dua tanggal, Anda dapat dengan mudah memeriksa apakah zona waktu kedua lebih kecil atau lebih besar dari zona waktu pertama yang Anda inginkan dan kurangi atau tambahkan waktu.

  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
sumber
0

GMT -03: 00 Contoh

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

Atau bahkan

now  = new Date().getTime()-3600*1000*3; // 1582818380528
data = new Date(now).toISOString();      // 2020-02-27T15:03:26.261Z
Rafael Xavier
sumber
-1

Ini berhasil untuk saya. Tidak yakin apakah itu ide yang bagus.

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
sumber
-1

Saya menggunakan paket 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());
},
Stephen Ince
sumber
-11

Ini adalah solusi TERBAIK

Menggunakan:

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

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

Kode:

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

Versi kopi:

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
sumber
2
Wow, saya juga tidak suka, tapi saya kira orang - orang benar - benar membenci Anda mengesampingkan prototipe builtin!
Josh dari Qaribou