Kasus satu:
new Date(Date.parse("Jul 8, 2005"));
Keluaran:
Jumat 08 Juli 2005 00:00:00 GMT-0700 (PST)
Kasus Dua:
new Date(Date.parse("2005-07-08"));
Keluaran:
Kamis 07 Juli 2005 17:00:00 GMT-0700 (PST)
Mengapa parse kedua salah?
javascript
date
pengguna121196
sumber
sumber
NaN
di Firefox, saya menemukan bahwa sebagian besar browser lain (dan Node.js) akan menguraikan tanggal tanpa hari, seperti "April 2014" sebagai 1 April 2014, tetapi Firefox mengembalikan NaN. Anda harus melewati tanggal yang tepat.Jawaban:
Sampai spec edisi ke-5 keluar,
Date.parse
metode ini sepenuhnya tergantung pada implementasi (new Date(string)
setara denganDate.parse(string)
kecuali yang terakhir mengembalikan nomor daripada aDate
). Dalam spesifikasi edisi ke-5 persyaratan ditambahkan untuk mendukung ISO-8601 yang disederhanakan (dan sedikit salah) (juga lihat Apa yang Dimaksud dengan String Waktu Tanggal dalam JavaScript? ). Tapi selain itu, ada tidak ada persyaratan untuk apaDate.parse
/new Date(string)
harus menerima selain itu mereka harus menerima apa punDate#toString
keluaran (tanpa mengatakan apa itu).Pada ECMAScript 2017 (edisi 8), implementasi diperlukan untuk mengurai output mereka untuk
Date#toString
danDate#toUTCString
, tetapi format string tersebut tidak ditentukan.Pada ECMAScript 2019 (edisi 9) format untuk
Date#toString
danDate#toUTCString
, telah ditentukan sebagai (masing-masing):misalnya Sel 10 Jul 2018 18:39:58 GMT + 0530 (IST)
mis. Sel 10 Jul 2018 13:09:58 GMT
menyediakan 2 format lagi yang
Date.parse
harus diuraikan secara andal dalam implementasi baru (mencatat bahwa dukungan tidak ada di mana-mana dan implementasi yang tidak patuh akan tetap digunakan untuk beberapa waktu).Saya akan merekomendasikan bahwa string tanggal diuraikan secara manual dan konstruktor Tanggal digunakan dengan argumen tahun, bulan dan hari untuk menghindari ambiguitas:
sumber
Date.parse
tidak berperilaku dengan format tanggal UK untuk beberapa alasan saya tidak bisa bekerjareturn new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
Berfungsi dengan sempurna, terima kasih!Selama pengalaman baru-baru ini menulis interpreter JS saya banyak bergulat dengan pekerjaan batin tanggal ECMA / JS. Jadi, saya pikir saya akan memasukkan 2 sen saya di sini. Semoga membagikan hal ini akan membantu orang lain dengan pertanyaan tentang perbedaan di antara browser tentang cara mereka menangani tanggal.
Sisi Input
Semua implementasi menyimpan nilai tanggal mereka secara internal sebagai angka 64-bit yang mewakili jumlah milidetik (ms) sejak 1970-01-01 UTC (GMT adalah hal yang sama dengan UTC). Tanggal ini adalah zaman ECMAScript yang juga digunakan oleh bahasa lain seperti sistem Java dan POSIX seperti UNIX. Tanggal yang terjadi setelah zaman adalah angka positif dan tanggal sebelumnya negatif.
Kode berikut ditafsirkan sebagai tanggal yang sama di semua browser saat ini, tetapi dengan offset zona waktu lokal:
Di zona waktu saya (EST, yaitu -05: 00), hasilnya adalah 18000000 karena itu berapa banyak ms dalam 5 jam (hanya 4 jam selama bulan-bulan musim panas). Nilainya akan berbeda di zona waktu yang berbeda. Perilaku ini ditentukan dalam ECMA-262 sehingga semua browser melakukannya dengan cara yang sama.
Meskipun ada beberapa variasi dalam format string input yang akan diurai oleh browser utama sebagai tanggal, mereka pada dasarnya menafsirkannya sama sejauh menyangkut zona waktu dan penghematan siang hari meskipun penguraian sebagian besar tergantung pada implementasi.
Namun, format ISO 8601 berbeda. Ini salah satu dari hanya dua format yang diuraikan dalam ECMAScript 2015 (ed 6) khusus yang harus diuraikan dengan cara yang sama oleh semua implementasi (yang lainnya adalah format yang ditentukan untuk Date.prototype.toString ).
Tetapi, bahkan untuk string format ISO 8601, beberapa implementasi salah. Berikut ini adalah perbandingan keluaran Chrome dan Firefox ketika jawaban ini awalnya ditulis untuk 1/1/1970 (zaman) di mesin saya menggunakan string format ISO 8601 yang harus diuraikan dengan nilai yang persis sama di semua implementasi:
Perbedaan ini telah diperbaiki pada tahun 2020, tetapi kebiasaan lain ada di antara browser saat mem-parsing string format ISO 8601.
Tapi itu semakin buruk. Sebuah kekhasan ECMA-262 adalah bahwa format hanya tanggal ISO 8601 (YYYY-MM-DD) harus diuraikan sebagai UTC, sedangkan ISO 8601 mengharuskannya untuk diuraikan sebagai lokal. Ini adalah output dari FF dengan format tanggal ISO panjang dan pendek tanpa penentu zona waktu.
Jadi yang pertama diurai sebagai lokal karena ini adalah ISO 8601 tanggal dan waktu tanpa zona waktu, dan yang kedua diurai sebagai UTC karena hanya ISO 8601 tanggal.
Jadi, untuk menjawab pertanyaan asli secara langsung,
"YYYY-MM-DD"
diperlukan oleh ECMA-262 untuk ditafsirkan sebagai UTC, sementara yang lain ditafsirkan sebagai lokal. Itu sebabnya:Ini tidak menghasilkan hasil yang setara:
Ini tidak:
Intinya adalah ini untuk menguraikan string tanggal. String HANYA ISO 8601 yang dapat Anda parsing dengan aman di browser adalah bentuk panjang dengan offset (baik ± HH: mm atau "Z"). Jika Anda melakukannya, Anda dapat dengan aman bolak-balik antara waktu lokal dan UTC.
Ini berfungsi di seluruh browser (setelah IE9):
Sebagian besar browser saat ini memperlakukan format input lain dengan setara, termasuk '1/1/1970' yang sering digunakan (M / D / YYYY) dan '1/1/1970 00:00:00 AM' (M / D / YYYY hh : mm: ss ap) format. Semua format berikut (kecuali yang terakhir) diperlakukan sebagai input waktu lokal di semua browser. Output dari kode ini sama di semua browser di zona waktu saya. Yang terakhir diperlakukan sebagai -05: 00 terlepas dari zona waktu host karena offset diatur dalam timestamp:
Namun, karena parsing bahkan format yang ditentukan dalam ECMA-262 tidak konsisten, disarankan untuk tidak pernah mengandalkan parser built-in dan untuk selalu mengurai string secara manual, katakanlah menggunakan perpustakaan dan berikan format ke parser.
Misalnya dalam moment.js Anda dapat menulis:
Sisi Keluaran
Di sisi output, semua browser menerjemahkan zona waktu dengan cara yang sama tetapi mereka menangani format string secara berbeda. Berikut adalah
toString
fungsi dan outputnya. PerhatikantoUTCString
dantoISOString
fungsi output jam 5:00 pagi di mesin saya. Juga, nama zona waktu mungkin merupakan singkatan dan mungkin berbeda dalam implementasi yang berbeda.Mengkonversi dari UTC ke Waktu lokal sebelum mencetak
Mencetak waktu UTC yang disimpan secara langsung
Saya biasanya tidak menggunakan format ISO untuk input string. Satu-satunya waktu yang menggunakan format itu bermanfaat bagi saya adalah ketika tanggal perlu disortir sebagai string. Format ISO dapat diurutkan apa adanya sedangkan yang lain tidak. Jika Anda harus memiliki kompatibilitas lintas-browser, tentukan zona waktu atau gunakan format string yang kompatibel.
Kode
new Date('12/4/2013').toString()
melewati transformasi pseudo-internal berikut:Saya harap jawaban ini bermanfaat.
sumber
Ada beberapa metode untuk kegilaan ini. Sebagai aturan umum, jika browser dapat menginterpretasikan tanggal sebagai ISO-8601, itu akan. "2005-07-08" termasuk dalam kamp ini, dan karena itu diuraikan sebagai UTC. "8 Jul 2005" tidak bisa, dan karena itu diuraikan dalam waktu setempat.
Lihat JavaScript dan Tanggal, What a Mess! untuk lebih.
sumber
Solusi lain adalah membangun array asosiatif dengan format tanggal dan kemudian memformat ulang data.
Metode ini berguna untuk tanggal yang diformat dengan cara yang tidak biasa.
Sebuah contoh:
sumber
Gunakan moment.js untuk mengurai tanggal:
Argumen ke-3 menentukan penguraian ketat (tersedia pada 2.3.0). Tanpanya moment.js juga dapat memberikan hasil yang salah.
sumber
Menurut http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html format "yyyy / mm / dd" memecahkan masalah yang biasa. Dia berkata: "Tetap pada" YYYY / MM / DD "untuk string tanggal Anda kapan pun memungkinkan. Ini didukung secara universal dan tidak ambigu. Dengan format ini, semua waktu bersifat lokal." Saya telah menetapkan tes: http://jsfiddle.net/jlanus/ND2Qg/432/ Format ini: + menghindari ambiguitas pesanan hari dan bulan dengan menggunakan pemesanan ymd dan tahun 4-digit + menghindari masalah UTC vs. lokal tidak mematuhi format ISO dengan menggunakan slash + danvk, the dygraphs guy, mengatakan bahwa format ini bagus di semua browser.
sumber
Sementara CMS benar bahwa meneruskan string ke metode parse umumnya tidak aman, spesifikasi ECMA-262 5th Edition (alias ES5) yang baru di bagian 15.9.4.2 menunjukkan bahwa
Date.parse()
sebenarnya harus menangani tanggal yang diformat ISO. Spesifikasi lama tidak membuat klaim seperti itu. Tentu saja, browser lama dan beberapa browser saat ini masih tidak menyediakan fungsi ES5 ini.Contoh kedua Anda tidak salah. Ini adalah tanggal yang ditentukan dalam UTC, sebagaimana tersirat oleh
Date.prototype.toISOString()
, tetapi diwakili dalam zona waktu lokal Anda.sumber
Perpustakaan parsing tanggal ringan ini harus menyelesaikan semua masalah yang sama. Saya suka perpustakaan karena sangat mudah diperluas. Mungkin juga i18n (tidak terlalu lurus ke depan, tetapi tidak terlalu sulit).
Contoh parsing:
Dan memformat kembali ke string (Anda akan melihat kedua kasus memberikan hasil yang persis sama):
sumber
Berikut ini adalah cuplikan singkat dan fleksibel untuk mengonversi string-datetime dengan cara lintas-browser yang aman seperti yang dijelaskan oleh nicel oleh @ drankin2112.
Browser Anda harus memberikan hasil cap waktu yang sama
Date.parse
dengan:sumber
Keduanya benar, tetapi mereka ditafsirkan sebagai tanggal dengan dua zona waktu yang berbeda. Jadi Anda membandingkan apel dan jeruk:
Saya menghapus
Date.parse()
panggilan karena digunakan secara otomatis pada argumen string. Saya juga membandingkan tanggal menggunakan format ISO8601 sehingga Anda dapat secara visual membandingkan tanggal antara tanggal lokal Anda dan tanggal UTC. Waktunya terpisah 7 jam, yang merupakan perbedaan zona waktu dan mengapa tes Anda menunjukkan dua tanggal yang berbeda.Cara lain untuk membuat tanggal lokal / UTC yang sama ini adalah:
Tapi saya masih sangat merekomendasikan Moment.js yang sederhana namun kuat :
sumber
The jawaban yang diterima dari CMS adalah benar, saya baru saja menambahkan beberapa fitur:
sumber