Tanggal tidak valid di safari

155
 alert(new Date('2010-11-29'));

chrome, ff tidak memiliki masalah dengan ini, tetapi safari berteriak "tanggal tidak valid". Mengapa

sunting: ok, sesuai komentar di bawah, saya menggunakan parsing string dan mencoba ini:

alert(new Date('11-29-2010')); //doesn't work in safari
alert(new Date('29-11-2010')); //doesn't work in safari
alert(new Date('2010-29-11')); //doesn't work in safari

sunting 22 Maret 2018 : Sepertinya orang masih mendarat di sini - Hari ini, saya akan menggunakan momentatau date-fnsselesai dengan itu. Date-fns juga bebas rasa sakit dan ringan.

Shrinath
sumber
Hanya untuk yang lain mencari masalah yang sama: Saya akhirnya menggunakan DateJS, yang menyelesaikan masalah saya secara keseluruhan .. Lihat jawaban yang diterima untuk detailnya.
Shrinath
2
gunakan moment.js untuk mengurai timestamp. Terutama ketika berhadapan dengan web lintas platform
Ming Yuen
1
Ini pertanyaan lama. Pada ECMAScript 2015, string hanya tanggal ISO 8601 diuraikan sebagai UTC. Namun, mungkin masih ada browser yang lebih tua di sekitarnya yang tidak akan menguraikannya sama sekali atau memperlakukannya sebagai lokal.
RobG

Jawaban:

167

Pola yyyy-MM-ddini bukan format yang didukung secara resmi untuk Datekonstruktor. Firefox tampaknya mendukungnya, tetapi jangan mengandalkan browser lain yang melakukan hal yang sama.

Berikut adalah beberapa string yang didukung:

  • MM-hh-tttt
  • yyyy / MM / dd
  • MM / hh / tttt
  • Dmm MMMM, tttt
  • MMM dd, tttt

DateJS tampaknya seperti pustaka yang bagus untuk mem -parsing format tanggal yang tidak standar.

Sunting : baru saja memeriksa ECMA-262 standar . Mengutip dari bagian 15.9.1.15:

Format String Waktu Tanggal

ECMAScript mendefinisikan format pertukaran string untuk tanggal-waktu berdasarkan penyederhanaan Format Diperpanjang ISO 8601. Formatnya adalah sebagai berikut: YYYY-MM-DDTHH: mm: ss.sssZ Di mana isiannya adalah sebagai berikut:

  • YYYY adalah angka desimal tahun ini di kalender Gregorian.
  • "-" (hyphon) muncul secara harfiah dua kali dalam string.
  • MM adalah bulan dalam setahun dari 01 (Januari) hingga 12 (Desember).
  • DD adalah hari dalam bulan dari 01 hingga 31.
  • "T" muncul secara harfiah dalam string, untuk menunjukkan awal elemen waktu.
  • HH adalah jumlah jam lengkap yang telah berlalu sejak tengah malam sebagai dua angka desimal.
  • ":" (titik dua) muncul secara harfiah dua kali dalam string.
  • mm adalah jumlah menit lengkap sejak awal jam sebagai dua digit desimal.
  • ss adalah jumlah detik lengkap sejak awal menit sebagai dua digit desimal.
  • "." (titik) muncul secara harfiah dalam string.
  • sss adalah jumlah milidetik lengkap sejak awal detik sebagai tiga angka desimal. Keduanya "." dan bidang milidetik dapat dihilangkan.
  • Z adalah offset zona waktu yang ditentukan sebagai "Z" (untuk UTC) atau "+" atau "-" diikuti oleh ekspresi waktu hh: mm

Format ini mencakup formulir hanya tanggal:

  • YYYY
  • YYYY-MM
  • YYYY-MM-DD

Ini juga mencakup formulir hanya waktu dengan offset zona waktu opsional ditambahkan:

  • THH: mm
  • THH: mm: dtk
  • THH: mm: ss.sss

Juga termasuk "tanggal-waktu" yang mungkin merupakan kombinasi dari yang di atas.

Jadi, sepertinya YYYY-MM-DD termasuk dalam standar, tetapi untuk beberapa alasan, Safari tidak mendukungnya.

Pembaruan : setelah melihat dokumentasi datejs , menggunakannya, masalah Anda harus diselesaikan menggunakan kode seperti ini:

var myDate1 = Date.parseExact("29-11-2010", "dd-MM-yyyy");
var myDate2 = Date.parseExact("11-29-2010", "MM-dd-yyyy");
var myDate3 = Date.parseExact("2010-11-29", "yyyy-MM-dd");
var myDate4 = Date.parseExact("2010-29-11", "yyyy-dd-MM");
darioo
sumber
4
Format ISO8601 digunakan dalam edisi ke-5 dari standar ECMAScript, dan belum didukung secara luas, cara teraman untuk menggunakan IMO, parsing tanggal secara manual :(
CMS
1
Itu sangat membantu dude .. Terima kasih .. :) Akhirnya berakhir menggunakan datejs untuk memformat.
Shrinath
bagi mereka di masa depan, harap dicatat bahwa datejs sangat fantastis dalam banyak hal, itu tidak menyelesaikan semua masalah format tanggal, terutama dengan safari. itu adalah PITA tetapi yang terbaik adalah melakukannya secara manual jika Anda masih memiliki masalah.
totallyNotLizards
@darioo Jadi saya mencoba jawaban Anda sebagai berikut: "var start = Date.parseExact (timestamp," YYYY-DD-MM HH: mm: SS ");" timestamp adalah "2016-01-28 00:00:00". Namun sekarang saya mendapatkan kesalahan, bahwa "Date.parseExact bukan fungsi". Tahukah Anda, apa yang terjadi di sini?
threxx
5
Masalah saya yang serupa disebabkan oleh Safari yang tidak tahu cara membaca zona waktu dalam format zona waktu RFC 822. Saya dapat memperbaikinya dengan menggunakan format ISO 8601. Jika Anda memiliki kontrol format tanggal saya mendapatkan ini berfungsi dengan "yyyy-MM-dd'T'HH: mm: ss.sssXXX" yang menciptakan yaitu. "2018-02-06T20: 00: 00.000 + 00: 00". Untuk alasan apa pun Safari tidak dapat membaca "2018-02-06T20: 00: 00.000 + 0000", perhatikan kurangnya titik dua dalam format zona waktu.
Olmstov
224

Bagi saya menerapkan perpustakaan baru hanya karena Safari tidak dapat melakukannya dengan benar terlalu banyak dan regex berlebihan. Inilah oneliner :

console.log (new Date('2011-04-12'.replace(/-/g, "/")));
Elzo Valugi
sumber
Jika mendapatkan tebasan hanya masalah saya, maka saya akan 'menerima' jawaban Anda (meskipun itu satu-satunya tujuan saya ketika saya mengajukan pertanyaan ini). Sekarang saya menemukan dateJS, saya mengimplementasikan MMM DD, format YYYY untuk pengalaman yang lebih ramah pengguna !!!
Shrinath
13
Bantuan satu baris ini sangat cocok untuk kebutuhan saya! Terima kasih!
Cyril N.
4
Ini juga cukup sederhana bagi saya. Tidak percaya Safari tidak suka - tetapi format yang sama dengan \\ berfungsi. Terima kasih @ Elzo dan terima kasih Shrinath karena memposting pertanyaan
Pete
1
Saya pikir ini adalah jawaban terbaik yang saya cenderung lupa / - / g bukannya '-'
Jacek Pietal
12
tepuk tangan karena tidak menerapkan perpustakaan.
lharby
56

Saya menghadapi masalah yang sama. Date.Parse("DATESTRING")sedang mengerjakan Chrome (Versi 59.0.3071.115) tetapi tidak untuk Safari (Versi 10.1.1 (11603.2.5))

Safari:

Date.parse("2017-01-22 11:57:00")
NaN

Chrome:

Date.parse("2017-01-22 11:57:00")
1485115020000

Solusi yang berhasil untuk saya adalah mengganti ruang di dateString dengan "T". (contoh dateString.replace(/ /g,"T"):)

Safari:

Date.parse("2017-01-22T11:57:00")
1485086220000

Chrome:

Date.parse("2017-01-22T11:57:00")
1485115020000

Perhatikan bahwa respons dari browser Safari adalah 8 jam (28800000 ms) kurang dari respons yang terlihat di browser Chrome karena Safari mengembalikan respons di TZ lokal (yang 8 jam di belakang UTC)

Untuk mendapatkan kedua waktu di TZ yang sama

Safari:

Date.parse("2017-01-22T11:57:00Z")
1485086220000

Chrome:

Date.parse("2017-01-22T11:57:00Z")
1485086220000
nizantz
sumber
Atau jika Anda tidak ingin keduanya sama di Safari dan Chrome, Anda bisa menggunakan new Date(year, month, date, hours, minutes, seconds, milliseconds)konstruktor. Parsing tanggal string ke array komponennya untuk menggunakan komponen-komponen itu di konstruktor. @nizantz akan lebih bagus jika Anda berpikir contoh seperti itu dapat ditambahkan ke jawaban Anda.
h3dkandi
Tidak terlalu berguna karena Anda mendapatkan tanggal dalam UTC dan bukan waktu setempat.
Jonas Äppelgran
1
dateString.replace(/ /g,"T")Baris kode ajaib ini berhasil membentuk saya. :)
Mazdak Shojaie
ganti (/ - / g, '/')
Jack Hu
11

Saya menggunakan momen untuk memecahkan masalah. Sebagai contoh

var startDate = moment('2015-07-06 08:00', 'YYYY-MM-DD HH:mm').toDate();
liwp_Stephen
sumber
10

Untuk mendapatkan solusi yang berfungsi pada sebagian besar browser, Anda harus membuat objek-tanggal Anda dengan format ini

(year, month, date, hours, minutes, seconds, ms)

misalnya:

dateObj = new Date(2014, 6, 25); //UTC time / Months are mapped from 0 to 11
alert(dateObj.getTime()); //gives back timestamp in ms

berfungsi baik dengan IE, FF, Chrome dan Safari. Bahkan versi yang lebih lama.

IE Dev Center: Obyek Tanggal (JavaScript)

Jaringan Pengembang Mozilla: Tanggal

Luxx
sumber
6

convert string to Date fromat (Anda harus tahu zona waktu server)

new Date('2015-06-16 11:00:00'.replace(/\s+/g, 'T').concat('.000+08:00')).getTime()  

di mana +08: 00 = timeZone dari server

Anja Ishmukhametova
sumber
Ini tidak memperhitungkan DST. TZ offset dapat berfluktuasi dan bergantung pada tanggal itu sendiri (dan waktu).
Costa
5

Saya memiliki masalah yang sama. Kemudian saya menggunakan moment.Js. Masalah telah menghilang.

Saat membuat momen dari string, pertama-tama kami memeriksa apakah string tersebut cocok dengan format ISO 8601 yang dikenal, kemudian kembali ke Date (string) baru jika format yang diketahui tidak ditemukan.

Peringatan: Dukungan browser untuk string parsing tidak konsisten. Karena tidak ada spesifikasi format yang harus didukung, apa yang berfungsi di beberapa browser tidak akan berfungsi di browser lain.

Untuk hasil yang konsisten mem-parsing selain string ISO 8601, Anda harus menggunakan String + Format.

misalnya

var date= moment(String);
Sampath
sumber
3

Meskipun Anda mungkin berharap bahwa browser akan mendukung ISO 8601 (atau himpunan-himpunan tanggal saja), ini bukan masalahnya. Semua browser yang saya tahu (setidaknya di AS / Inggris yang saya gunakan) dapat mem-parsing MM/DD/YYYYformat AS yang mengerikan .

Jika Anda sudah memiliki bagian-bagian tanggal, Anda mungkin ingin mencoba menggunakan Date.UTC () . Jika tidak, tetapi Anda harus menggunakan YYYY-MM-DDformat, saya sarankan menggunakan ekspresi reguler untuk mengurai potongan yang Anda tahu dan kemudian meneruskannya Date.UTC().

Phrogz
sumber
Saya kira string parsing adalah cara untuk pergi :(
Shrinath
1

Gunakan format di bawah ini, itu akan berfungsi pada semua browser

var year = 2016;
var month = 02;           // month varies from 0-11 (Jan-Dec)
var day = 23;

month = month<10?"0"+month:month;        // to ensure YYYY-MM-DD format
day = day<10?"0"+day:day;

dateObj = new Date(year+"-"+month+"-"+day);

alert(dateObj); 

// Output Anda akan terlihat seperti ini "Rab 23 Mar 2016 00:00:00 GMT + 0530 (IST)"

// Perhatikan ini akan berada di zona waktu saat ini dalam hal ini dilambangkan oleh IST, untuk dikonversi ke zona waktu UTC yang dapat Anda sertakan

alert(dateObj.toUTCSting);

// Keluaran Anda sekarang akan seperti ini "Sel, 22 Mar 2016 18:30:00 GMT"

Perhatikan bahwa sekarang dateObj menunjukkan waktu dalam format GMT, juga perhatikan bahwa tanggal dan waktu telah diubah secara bersamaan.

Fungsi "toUTCSting" mengambil waktu yang sesuai di meridian Greenwich. Ini dicapai dengan menetapkan perbedaan waktu antara zona waktu Anda saat ini dengan zona waktu Greenwich Meridian.

Dalam kasus di atas waktu sebelum konversi adalah 00:00 jam dan menit pada tanggal 23 Maret di tahun 2016. Dan setelah konversi dari GMT + 0530 (IST) jam ke GMT (pada dasarnya mengurangi 5,30 jam dari cap waktu yang diberikan dalam kasus) waktu mencerminkan 18,30 jam pada tanggal 22 Maret di tahun 2016 (tepatnya 5,30 jam di belakang pertama kali).

Selanjutnya untuk mengkonversi objek tanggal ke cap waktu yang dapat Anda gunakan

alert(dateObj.getTime());

// output akan terlihat mirip dengan "1458671400000" ini

Ini akan memberi Anda cap waktu yang unik saat itu

Abhay Aradhya
sumber
1

Bagaimana dengan pembajakan Datedengan fix-date ? Tidak ada dependensi, min + gzip = 280 B

kenberkeley
sumber
1

Cara terbaik untuk melakukannya adalah dengan menggunakan format berikut:

new Date(year, month, day, hours, minutes, seconds, milliseconds)
var d = new Date(2018, 11, 24, 10, 33, 30, 0);

Ini didukung di semua browser dan tidak akan memberi Anda masalah. Harap dicatat bahwa bulan ditulis dari 0 hingga 11.

Daniël Brito
sumber
Bekerja dengan baik di Safari dan Chrome, tetapi masih memiliki masalah di Firefox. Safari: var date = Tanggal baru (2018,06,08,19,17) Sun 08 Jul 2018 19:17:00 GMT + 0800 (+08) Chrome: var date = Tanggal baru (2018,06,08,19, 17) Sun 08 Jul 2018 19:17:00 GMT + 0800 (Waktu Malaysia) Firefox: var date = Tanggal baru (2018,06,08,19,17) Tanggal 2018-07-08T11: 17: 00.000Z
Biranchi
0

Masalah yang sama dihadapi di Safari dan diselesaikan dengan memasukkan ini ke halaman web

 <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"></script> 

Semoga ini akan berhasil juga untuk Anda

Terima kasih

Yasir Shabbir Choudhary
sumber
Menurut Anda mengapa ini akan berhasil? Saya melihat skrip dan sepertinya tidak menimpa metode dalam objek Date. Aku pergi di sini: polyfill.io/v3/url-builder dan sepertinya tidak ada tentang tanggal parsing.
Costa
0

Seperti @nizantz disebutkan sebelumnya, menggunakan Date.parse () tidak berfungsi untuk saya di Safari. Setelah sedikit riset, saya mengetahui bahwa properti LastDateModified untuk objek File telah ditinggalkan, dan tidak lagi didukung oleh Safari. Menggunakan properti LastModified dari objek File menyelesaikan masalah saya. Tentu tidak suka ketika info buruk ditemukan online.

Terima kasih kepada semua yang berkontribusi pada posting ini yang telah membantu saya dalam menempuh jalan yang saya butuhkan untuk belajar tentang masalah saya. Kalau bukan karena info ini, saya tidak akan pernah mungkin menemukan masalah root saya. Mungkin ini akan membantu orang lain dalam situasi serupa saya.

S. Costello
sumber
0

Saya juga menghadapi masalah yang sama di Safari Browser

var date = new Date("2011-02-07");
console.log(date) // IE you get ‘NaN’ returned and in Safari you get ‘Invalid Date’

Di sini solusinya:

var d = new Date(2011, 01, 07); // yyyy, mm-1, dd  
var d = new Date(2011, 01, 07, 11, 05, 00); // yyyy, mm-1, dd, hh, mm, ss  
var d = new Date("02/07/2011"); // "mm/dd/yyyy"  
var d = new Date("02/07/2011 11:05:00"); // "mm/dd/yyyy hh:mm:ss"  
var d = new Date(1297076700000); // milliseconds  
var d = new Date("Mon Feb 07 2011 11:05:00 GMT"); // ""Day Mon dd yyyy hh:mm:ss GMT/UTC 
venkatskpi
sumber
0

Ini bukan solusi terbaik, walaupun saya hanya menangkap kesalahan dan mengirim kembali tanggal saat ini. Saya pribadi merasa tidak menyelesaikan masalah Safari, jika pengguna ingin menggunakan browser yang tidak memenuhi standar sh * t - mereka harus hidup dengan kebiasaan.

function safeDate(dateString = "") {
  let date = new Date();
  try {
    if (Date.parse(dateString)) {
      date = new Date(Date.parse(dateString))
    }
  } catch (error) {
    // do nothing.
  }
  return date;
}

Saya sarankan agar backend Anda mengirim tanggal ISO.

AndrewMcLagan
sumber
Dengan segala hormat, ketika Anda bermaksud pengguna harus menggunakan browser yang Anda buat kode, itu terlihat buruk secara umum. Ini juga tergantung pada kasus penggunaan dan target pemirsa kami - jika situs web sedang dibangun untuk konsumsi pasar massal, setidaknya kami juga akan mendukung IE10. Saya yakin seseorang di MS berpikiran sama ketika mereka mendesain / coding untuk internet explorer. Kita semua tahu bagaimana ini dibicarakan sekarang.
Shrinath
-1

gunakan format 'mm / hh / tttt'. Misalnya: - Tanggal baru ('02 / 28/2015 '). Ini bekerja dengan baik di semua browser.

Ravi S
sumber