L'analyse des dates en javascript est différente entre safari et chrome

J'ai le code suivant

var c = new Date(Date.parse("2011-06-21T14:27:28.593Z"));
console.log(c);

Sur Chrome il imprime correctement la date sur la console. Dans Safari il échoue. Qui est correct et plus important encore Quelle est la meilleure façon pour gérer cela?

47
demandé sur bradgonesurfing 2011-06-21 18:44:07

8 réponses

Vous ne pouvez pas vraiment utiliser la Date.analyser. Je vous suggère d'utiliser: new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )

Pour diviser la chaîne, vous pouvez essayer

var s = '2011-06-21T14:27:28.593Z';
var a = s.split(/[^0-9]/);
//for (i=0;i<a.length;i++) { alert(a[i]); }
var d=new Date (a[0],a[1]-1,a[2],a[3],a[4],a[5] );
alert(s+ " "+d);
82
répondu Erik 2011-06-22 20:09:54

J'ai tendance à éviter Date.parse, selon les autres réponses à cette question. Il ne semble pas être un moyen portable de traiter de manière fiable avec les dates.

Au lieu de cela, j'ai utilisé quelque chose comme la fonction ci-dessous. Cela utilise jQuery pour mapper le tableau de chaînes dans un tableau de nombres, mais c'est une dépendance assez facile à supprimer / modifier. J'inclus également ce que je considère comme des valeurs par défaut raisonnables, pour vous permettre d'analyser 2007-01-09 et 2007-01-09T09:42:00 en utilisant la même fonction.

function dateFromString(str) {
  var a = $.map(str.split(/[^0-9]/), function(s) { return parseInt(s, 10) });
  return new Date(a[0], a[1]-1 || 0, a[2] || 1, a[3] || 0, a[4] || 0, a[5] || 0, a[6] || 0);
}
13
répondu jabley 2013-06-03 09:00:31

, je l'ai vérifié dans plusieurs navigateurs, et oui, safari retourne invalid date. Au fait, vous n'avez pas besoin d'utiliser Date.parse ici, juste {[4] } fonctionnera aussi. Safari nécessite évidemment plus de formatage de la chaîne de date que vous fournissez. Si vous remplacez ' - 'par'/', supprimez le T et tout après le point (.593Z), il vous donnera une date valide. Ce code est testé et fonctionne dans Safari

var datestr = '2011-06-21T14:27:28.593Z'.split(/[-T.]/);
var safdat = new Date( datestr.slice(0,3).join('/')+' '+datestr[3] );

Ou en utilisant String.replace(...):

new Date("2016-02-17T00:05:01+0000".replace(/-/g,'/').replace('T',' ').replace(/(\..*|\+.*/,""))
9
répondu KooiInc 2016-02-17 01:28:53

Mon problème similaire a été causé par Safari ne sachant pas comment lire le fuseau horaire dans un format de fuseau horaire RFC 822. J'ai pu résoudre ce problème en utilisant le format ISO 8601. Si vous avez le contrôle du format de date, cela fonctionne avec SimpleDateFormat de java " yyyy-MM-dd'THH:mm: ss.sssXXX " qui produit pour moi ie. "2018-02-06T20:00:00.000+04:00". Pour une raison quelconque Safari ne peut pas lire "2018-02-06T20 :00: 00.000 + 0400", notez l'absence de deux-points dans le format de fuseau horaire.

// Works
var c = new Date("2018-02-06T20:00:00.000+04:00"));
console.log(c);

// Doesn't work
var c = new Date("2018-02-06T20:00:00.000+0400"));
console.log(c);
6
répondu Olmstov 2018-03-06 19:27:45

J'ai fini par utiliser une bibliothèque pour compenser cela:

Http://zetafleet.com/blog/javascript-dateparse-for-iso-8601

Une fois que cette bibliothèque a été incluse, vous utilisez ce code pour créer la nouvelle date:

var date = new Date(Date.parse(datestring));

Notre projet n'utilisait pas de spécificateurs millisecondes, mais je ne crois pas que cela causera un problème pour vous.

5
répondu AaronSieb 2011-09-13 21:18:41

J'utilise la fonction suivante pour analyser les dates avec le fuseau horaire. Fonctionne bien à la fois Chrome et Safari:

function parseDate(date) {
  const parsed = Date.parse(date);
  if (!isNaN(parsed)) {
    return parsed;
  }

  return Date.parse(date.replace(/-/g, '/').replace(/[a-z]+/gi, ' '));
}

console.log(parseDate('2017-02-09T13:22:18+0300'));  // 1486635738000 time in ms
2
répondu Londeren 2017-02-17 07:22:00

J'ai essayé la date convertie en la tronquant et en l'analysant comme ça, cela fonctionne bien avec safari et ios .

var dateString = "2016-01-22T08:18:10.000+0000";
 var hours = parseInt(dateString.split("+")[1].substr("0","2"));
 var mins = parseInt(dateString.split("+")[1].substr("2"));
 var date = new Date(dateString.split("+")[0]);
 date.setHours(date.getHours()-hours);
 date.setMinutes(date.getMinutes()-mins);
1
répondu Anky 2016-01-27 05:07:51

Au lieu d'utiliser 'Z' à la fin de la chaîne de date, vous pouvez ajouter le décalage du fuseau horaire du client local. Vous voudrez probablement une méthode pour générer cela pour vous:

let timezoneOffset = () => {
    let date = new Date(),
        timezoneOffset = date.getTimezoneOffset(),
        hours = ('00' + Math.floor(Math.abs(timezoneOffset/60))).slice(-2),
        minutes = ('00' + Math.abs(timezoneOffset%60)).slice(-2),
        string = (timezoneOffset >= 0 ? '-' : '+') + hours + ':' + minutes;
    return string;
}

Donc le résultat final serait:

var c = new Date("2011-06-21T14:27:28.593" + timezoneOffset());

0
répondu adjwilli 2018-04-27 19:55:07