web-dev-qa-db-fra.com

Comment formater ISO 8601 avec un décalage horaire en JavaScript?

Objectif: Trouvez le local time et UTC time offset, puis construisez l'URL au format suivant.

Exemple d’URL:/Actions/Sleep? Duration = 2002-10-10T12: 00: 00−05: 00

Le format est basé sur la recommandation du W3C: http://www.w3.org/TR/xmlschema11-2/#dateTime

La documentation dit:

Par exemple, 2002-10-10T12: 00: 00–05: 00 (midi le 10 octobre 2002, heure avancée du Centre et heure normale de l'Est des États-Unis) est égal à 2002-10-10T17: 00: 00Z, cinq heures plus tard que 2002-10-10T12: 00: 00Z.

Donc, en fonction de ma compréhension, je dois trouver mon heure locale par nouvelle Date (), puis utiliser la fonction getTimezoneOffset () pour calculer la différence, puis l’attacher à la fin de la chaîne.

1.Obtenir l'heure locale avec le format

var local = new Date().format("yyyy-MM-ddThh:mm:ss"); //today (local time)

sortie

2013-07-02T09:00:00

2.Obtenez le temps UTC compensé par heure

var offset = local.getTimezoneOffset() / 60;

sortie

7

URL de 3.Construct (partie de temps seulement)

var duration = local + "-" + offset + ":00";

sortie:

2013-07-02T09:00:00-7:00

La sortie ci-dessus signifie que mon heure locale est le 02/07/2013 et la différence par rapport à l'heure UTC est de 7 heures (l'heure UTC est de 7 heures en avance sur l'heure locale)

Jusqu'à présent, cela semble fonctionner, mais si getTimezoneOffset () renvoie une valeur négative telle que -120?

Je me demande comment le format devrait ressembler dans ce cas car je ne peux pas comprendre le document W3C. Merci d'avance.

83
masato-san

Ce qui suit devrait fonctionner correctement, et pour tous les navigateurs (merci à @MattJohnson pour le conseil)

Date.prototype.toIsoString = function() {
    var tzo = -this.getTimezoneOffset(),
        dif = tzo >= 0 ? '+' : '-',
        pad = function(num) {
            var norm = Math.floor(Math.abs(num));
            return (norm < 10 ? '0' : '') + norm;
        };
    return this.getFullYear() +
        '-' + pad(this.getMonth() + 1) +
        '-' + pad(this.getDate()) +
        'T' + pad(this.getHours()) +
        ':' + pad(this.getMinutes()) +
        ':' + pad(this.getSeconds()) +
        dif + pad(tzo / 60) +
        ':' + pad(tzo % 60);
}

var dt = new Date();
console.log(dt.toIsoString());
149
Steven Moseley

getTimezoneOffset() renvoie le signe opposé du format requis par la spécification que vous avez référencée.

Ce format est également appelé ISO8601 , ou plus précisément RFC3339 .

Dans ce format, UTC est représenté par un Z tandis que tous les autres formats sont représentés par un décalage par rapport à UTC. La signification est la même que celle de JavaScript, mais l'ordre de soustraction étant inversé, le résultat porte le signe opposé.

De plus, il n'y a pas de méthode sur l'objet Date natif appelé format, donc votre fonction dans # 1 échouera à moins que vous n'utilisiez une bibliothèque pour y parvenir. Reportez-vous à cette documentation .

Si vous recherchez une bibliothèque pouvant fonctionner directement avec ce format, je vous recommande d'essayer moment.js . En fait, c'est le format par défaut, vous pouvez donc faire ceci:

var m = moment();    // get "now" as a moment
var s = m.format();  // the ISO format is the default so no parameters are needed

// sample output:   2013-07-01T17:55:13-07:00

Il s'agit d'une solution multi-navigateur bien testée et dotée de nombreuses autres fonctionnalités utiles.

62
Matt Johnson-Pint

C’est ma fonction pour le fuseau horaire du client, c’est léger et simple.

  function getCurrentDateTimeMySql() {        
      var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
      var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, 19).replace('T', ' ');
      var mySqlDT = localISOTime;
      return mySqlDT;
  }
2
Bbb

Vérifie ça:

function dateToLocalISO(date) {
    const off    = date.getTimezoneOffset()
    const absoff = Math.abs(off)
    return (new Date(date.getTime() - off*60*1000).toISOString().substr(0,23) +
            (off > 0 ? '-' : '+') + 
            (absoff / 60).toFixed(0).padStart(2,'0') + ':' + 
            (absoff % 60).toString().padStart(2,'0'))
}

// Test it:
d = new Date()

dateToLocalISO(d)
// ==> '2019-06-21T16:07:22.181-03:00'

// Is similar to:

moment = require('moment')
moment(d).format('YYYY-MM-DDTHH:mm:ss.SSSZ') 
// ==> '2019-06-21T16:07:22.181-03:00'
0
Nahuel Greco

Juste mes deux envois ici

Je faisais face à ce problème avec datetime alors ce que j'ai fait est la suivante:

const moment = require('moment-timezone')

const date = moment.tz('America/Bogota').format()

Enregistrez ensuite la date en db pour pouvoir la comparer à partir d’une requête.


Pour installer moment-timezone

npm i moment-timezone
0
Arnold Gandarillas