Data non valida in Safari


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

chrome, ff non ha problemi con questo, ma Safari piange "data non valida". Perché ?

modifica: ok, come da commenti qui sotto, ho usato l'analisi delle stringhe e ho provato questo:

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

modifica 22 marzo 2018 : sembra che le persone stiano ancora atterrando qui - Oggi userei momento avrei date-fnsfinito. Date-fns è anche molto indolore e leggero.


Solo per guardare lo stesso problema: ho finito con l'uso di DateJS, che ha risolto il mio problema in generale. Vedi la risposta accettata per i dettagli.
Shrinath,

2
usa moment.js per analizzare il timestamp. Soprattutto quando si tratta di web multipiattaforma
Ming Yuen il

1
Questa è una vecchia domanda. A partire da ECMAScript 2015, le stringhe di sola data ISO 8601 vengono analizzate come UTC. Tuttavia, potrebbero esserci ancora dei browser meno recenti che non lo analizzeranno affatto o lo tratteranno come locale.
RobG

Risposte:


167

Il modello yyyy-MM-ddnon è un formato ufficialmente supportato per il Datecostruttore. Firefox sembra supportarlo, ma non contare su altri browser che fanno lo stesso.

Ecco alcune stringhe supportate:

  • MM-GG-AAAA
  • dd yyyy / MM /
  • MM / gg / aaaa
  • MMMM gg, aaaa
  • MMM gg, aaaa

DateJS sembra una buona libreria per l'analisi di formati di data non standard.

Modifica : appena verificato lo standard ECMA-262 . Citando dalla sezione 15.9.1.15:

Formato data e ora stringa

ECMAScript definisce un formato di interscambio di stringhe per data-ora basato su una semplificazione del formato esteso ISO 8601. Il formato è il seguente: AAAA-MM-GGTHH: mm: ss.sssZ Dove i campi sono i seguenti:

  • AAAA sono le cifre decimali dell'anno nel calendario gregoriano.
  • "-" (hyphon) appare letteralmente due volte nella stringa.
  • MM è il mese dell'anno dal 01 (gennaio) al 12 (dicembre).
  • DD è il giorno del mese dall'01 al 31.
  • "T" appare letteralmente nella stringa, per indicare l'inizio dell'elemento time.
  • HH è il numero di ore complete trascorse dalla mezzanotte come due cifre decimali.
  • ":" (due punti) appare letteralmente due volte nella stringa.
  • mm è il numero di minuti completi dall'inizio dell'ora come due cifre decimali.
  • ss è il numero di secondi completi dall'inizio del minuto sotto forma di due cifre decimali.
  • "" (punto) appare letteralmente nella stringa.
  • sss è il numero di millisecondi completi dall'inizio del secondo come tre cifre decimali. Sia il "." e il campo dei millisecondi può essere omesso.
  • Z è l'offset del fuso orario specificato come "Z" (per UTC) o "+" o "-" seguito da un'espressione temporale hh: mm

Questo formato include moduli di sola data:

  • AAAA
  • AAAA-MM
  • AAAA-MM-DD

Include anche moduli di sola ora con un offset di fuso orario opzionale aggiunto:

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

Sono inclusi anche "date-time" che possono essere una qualsiasi combinazione di quanto sopra.

Quindi, sembra che YYYY-MM-DD sia incluso nello standard, ma per qualche motivo, Safari non lo supporta.

Aggiornamento : dopo aver visto la documentazione di datejs , usandola, il tuo problema dovrebbe essere risolto usando un codice come questo:

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

4
Il formato ISO8601 viene utilizzato nella quinta edizione dello standard ECMAScript e non è ancora ampiamente supportato, il modo più sicuro per accedere all'IMO, analizzare la data manualmente :(
CMS

1
È stato molto utile amico ... Grazie .. :) Finalmente ho finito con l'uso di datejs per la formattazione.
Shrinath,

per quelli in futuro, tieni presente che sebbene datejs sia fantastico sotto molti aspetti, non risolve tutti i problemi di formattazione della data, in particolare con Safari. è un PITA ma è meglio farlo manualmente se hai ancora problemi.
totallyNotLizards

@darioo Quindi ho provato la tua risposta come segue: "var start = Date.parseExact (timestamp," YYYY-DD-MM HH: mm: SS ");" il timestamp è "28-01-2016 00:00:00". Tuttavia ora ricevo l'errore che "Date.parseExact non è una funzione". Sai cosa sta succedendo qui?
threxx,

5
Il mio problema simile è stato causato dal fatto che Safari non sapeva leggere il fuso orario in un formato di fuso orario RFC 822. Sono stato in grado di risolvere questo problema utilizzando il formato ISO 8601. Se hai il controllo del formato della data, ho funzionato con "yyyy-MM-dd'T'HH: mm: ss.sssXXX" che crea cioè. "2018-02-06T20: 00: 00.000 + 00: 00". Per qualsiasi motivo Safari non è in grado di leggere "2018-02-06T20: 00: 00.000 + 0000", notare la mancanza di due punti nel formato del fuso orario.
Olmstov,

224

Per me implementare una nuova libreria solo perché Safari non può farlo correttamente è troppo e una regex è eccessiva. Ecco l' oneliner :

console.log (new Date('2011-04-12'.replace(/-/g, "/")));

Se ottenere una barra fosse solo un mio problema, avrei "accettato" la tua risposta (sebbene fosse il mio unico obiettivo quando ho posto questa domanda). Ora che ho trovato dateJS, ho implementato MMM DD, formato YYYY per un'esperienza più user friendly !!!
Shrinath,

13
Questo aiuto di una riga era perfetto per le mie necessità! Grazie!
Cyril N.

4
Questo è stato abbastanza semplice anche per me. Non riesco a credere che a Safari non piaccia il - ma lo stesso formato con un \\ funziona. Grazie @Elzo e grazie Shrinath per aver pubblicato la domanda
Pete,

1
Penso che questa sia la migliore risposta che tendo a dimenticare / - / g invece di '-'
Jacek Pietal,

12
applausi per non aver implementato una biblioteca.
Lharby,

56

Stavo affrontando un problema simile. Date.Parse("DATESTRING")funzionava su Chrome (versione 59.0.3071.115) ma non su Safari (versione 10.1.1 (11603.2.5))

Safari:

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

Cromo:

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

La soluzione che ha funzionato per me è stata la sostituzione dello spazio con dateString "T". (esempio dateString.replace(/ /g,"T"):)

Safari:

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

Cromo:

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

Tieni presente che la risposta dal browser Safari è di 8 ore (28800000 ms) in meno rispetto alla risposta vista nel browser Chrome perché Safari ha restituito la risposta in TZ locale (che è di 8 ore dietro UTC)

Per ottenere entrambi i tempi nella stessa TZ

Safari:

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

Cromo:

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

Oppure se non vuoi che entrambe le date siano uguali in Safari e Chrome puoi usare il new Date(year, month, date, hours, minutes, seconds, milliseconds)costruttore. Analizzare la data della stringa su una matrice dei suoi componenti al fine di utilizzare tali componenti nel costruttore. @nizantz sarebbe bello se pensi che tale esempio possa essere aggiunto alla tua risposta.
h3dkandi,

Non particolarmente utile poiché si ottiene la data in UTC e non l'ora locale.
Jonas Äppelgran,

1
Questa dateString.replace(/ /g,"T")linea magica di codice ha funzionato da me. :)
Mazdak Shojaie,

sostituisci (/ - / g, '/')
Jack Hu

11

Uso il momento per risolvere il problema. Per esempio

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

10

Per avere una soluzione funzionante sulla maggior parte dei browser, è necessario creare l'oggetto data con questo formato

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

per esempio:

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

funziona bene con IE, FF, Chrome e Safari. Anche versioni precedenti.

IE Dev Center: Date Object (JavaScript)

Mozilla Dev Network: Data


6

converti la stringa in Date fromat (devi conoscere il fuso orario del server)

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

dove +08: 00 = fuso orario dal server


Ciò non tiene conto dell'ora legale. L'offset TZ può variare e dipende dalla data stessa (e dall'ora).
costa,

5

Ho avuto lo stesso problema, quindi ho usato moment.Js. Il problema è svanito.

Quando creiamo un momento da una stringa, controlliamo prima se la stringa corrisponde ai formati ISO 8601 noti, quindi torniamo alla nuova data (stringa) se non viene trovato un formato noto.

Avviso: il supporto del browser per l'analisi delle stringhe è incoerente. Poiché non esiste alcuna specifica su quali formati devono essere supportati, ciò che funziona in alcuni browser non funzionerà in altri browser.

Per risultati coerenti analizzando qualsiasi cosa diversa dalle stringhe ISO 8601, è necessario utilizzare String + Format.

per esempio

var date= moment(String);

3

Anche se potresti sperare che i browser supportino ISO 8601 (o relativi sottoinsiemi di sole date), non è così. Tutti i browser che conosco (almeno nelle versioni US / English che uso) sono in grado di analizzare l'orribile MM/DD/YYYYformato USA .

Se hai già le parti della data, potresti invece provare a usare Date.UTC () . Se non lo fai, ma devi usare il YYYY-MM-DDformato, ti suggerisco di usare un'espressione regolare per analizzare i pezzi che conosci e poi passarli Date.UTC().


Immagino che l'analisi delle stringhe sia la strada da percorrere :(
Shrinath il

1

Utilizza il formato seguente, funzionerebbe su tutti i 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); 

// Il risultato sarà simile a "Mer 23 mar 2016 00:00:00 GMT + 0530 (IST)"

// Nota che questo sarebbe nel fuso orario corrente in questo caso indicato da IST, per convertire in fuso orario UTC che puoi includere

alert(dateObj.toUTCSting);

// La tua uscita ora vorrebbe questo "Mar, 22 Mar 2016 18:30:00 GMT"

Si noti che ora dateObj mostra l'ora nel formato GMT, inoltre si noti che la data e l'ora sono state modificate di conseguenza.

La funzione "toUTCSting" recupera l'ora corrispondente nel meridiano di Greenwich. Ciò si ottiene stabilendo la differenza oraria tra il fuso orario corrente e il fuso orario Meridiano di Greenwich.

Nel caso sopra il tempo prima della conversione era di 00:00 ore e minuti il ​​23 marzo dell'anno 2016. E dopo la conversione da GMT + 0530 (IST) ore a GMT (sottrae sostanzialmente 5.30 ore dalla data indicata in questo caso) il tempo riflette le 18.30 del 22 marzo dell'anno 2016 (esattamente 5.30 ore dopo la prima volta).

Inoltre, puoi convertire qualsiasi oggetto data in data / ora che puoi utilizzare

alert(dateObj.getTime());

// l'output sarebbe simile a questo "1458671400000"

Questo ti darebbe il timestamp unico del tempo



1

Il modo migliore per farlo è utilizzando il seguente formato:

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

Questo è supportato in tutti i browser e non ti darà alcun problema. Si noti che i mesi sono scritti da 0 a 11.


Funziona bene su Safari e Chrome, ma presenta ancora problemi su Firefox. Safari: var date = new Date (2018,06,08,19,17) dom 08 lug 2018 19:17:00 GMT + 0800 (+08) Chrome: var date = new Date (2018,06,08,19, 17) dom 08 lug 2018 19:17:00 GMT + 0800 (ora della Malesia) Firefox: var date = new Date (2018,06,08,19,17) data 2018-07-08T11: 17: 00.000Z
Biranchi

0

Lo stesso problema riscontrato in Safari ed è stato risolto inserendolo nella pagina web

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

Spero che funzioni anche nel tuo caso

Grazie


Perché pensi che funzionerebbe? Ho guardato lo script e non sembra sovrascrivere i metodi nell'oggetto Date. Sono andato qui: polyfill.io/v3/url-builder e sembra non esserci nulla sulle analisi delle date.
costa

0

Come accennato in precedenza @nizantz, l'utilizzo di Date.parse () non funzionava per me in Safari. Dopo un po 'di ricerche, ho appreso che la proprietà lastDateModified per l'oggetto File è stata deprecata e non è più supportata da Safari. L'uso della proprietà lastModified dell'oggetto File ha risolto i miei problemi. Non ti dispiacerà quando vengono trovate informazioni negative online.

Grazie a tutti coloro che hanno contribuito a questo post che mi hanno aiutato a seguire il percorso che avevo bisogno di conoscere il mio problema. Se non fosse stato per queste informazioni, probabilmente non avrei mai capito il mio problema di root. Forse questo aiuterà qualcun altro nella mia situazione simile.


0

Inoltre sto affrontando lo stesso problema in Safari Browser

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

Ecco la soluzione:

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 

0

Questa non è la soluzione migliore, anche se rilevo semplicemente l'errore e rispedisco la data corrente. Personalmente ho voglia di non risolvere i problemi di Safari, se gli utenti vogliono utilizzare un browser non conforme allo standard, devono convivere con le stranezze.

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

Suggerirei al tuo backend di inviare le date ISO.


Con tutto il rispetto, quando intendi che gli utenti devono usare il browser per cui hai scritto il codice, questo sembra male in senso generale. Dipende anche dai nostri casi d'uso e dal pubblico di destinazione: se un sito Web è stato creato per il consumo del mercato di massa, supporteremmo almeno IE10. Sono sicuro che qualcuno nella SM ha pensato allo stesso modo durante la progettazione / programmazione di Internet Explorer. Sappiamo tutti come si parla ora.
Shrinath,

-1

usa il formato 'mm / gg / aaaa'. Ad esempio: - nuova data ('02 / 28/2015 '). Funziona bene in tutti i browser.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.