web-dev-qa-db-fra.com

Comment sortir une chaîne au format ISO 8601 en JavaScript?

J'ai un objet Date. Comment puis-je restituer la portion title de l'extrait suivant?

<abbr title="2010-04-02T14:12:07">A couple days ago</abbr>

J'ai la partie "temps relatif en mots" d'une autre bibliothèque.

J'ai essayé ce qui suit:

function isoDate(msSinceEpoch) {

   var d = new Date(msSinceEpoch);
   return d.getUTCFullYear() + '-' + (d.getUTCMonth() + 1) + '-' + d.getUTCDate() + 'T' +
          d.getUTCHours() + ':' + d.getUTCMinutes() + ':' + d.getUTCSeconds();

}

Mais cela me donne:

"2010-4-2T3:19"
237
James A. Rosen

Il existe déjà une fonction appelée toISOString()

var date = new Date();
date.toISOString(); //"2011-12-19T15:28:46.493Z"

Si, d'une manière ou d'une autre, vous êtes sur un navigateur qui ne le supporte pas, je vous ai couvert:

if ( !Date.prototype.toISOString ) {
  ( function() {

    function pad(number) {
      var r = String(number);
      if ( r.length === 1 ) {
        r = '0' + r;
      }
      return r;
    }

    Date.prototype.toISOString = function() {
      return this.getUTCFullYear()
        + '-' + pad( this.getUTCMonth() + 1 )
        + '-' + pad( this.getUTCDate() )
        + 'T' + pad( this.getUTCHours() )
        + ':' + pad( this.getUTCMinutes() )
        + ':' + pad( this.getUTCSeconds() )
        + '.' + String( (this.getUTCMilliseconds()/1000).toFixed(3) ).slice( 2, 5 )
        + 'Z';
    };

  }() );
}
426
Anatoly Mironov

Voir le dernier exemple à la page https://developer.mozilla.org/fr/Core_JavaScript_1.5_Reference:Global_Objects:Date :

/* Use a function for the exact format desired... */
function ISODateString(d) {
    function pad(n) {return n<10 ? '0'+n : n}
    return d.getUTCFullYear()+'-'
         + pad(d.getUTCMonth()+1)+'-'
         + pad(d.getUTCDate())+'T'
         + pad(d.getUTCHours())+':'
         + pad(d.getUTCMinutes())+':'
         + pad(d.getUTCSeconds())+'Z'
}

var d = new Date();
console.log(ISODateString(d)); // Prints something like 2009-09-28T19:03:12Z
63
dev-null-dweller

Presque toutes les méthodes to-ISO sur le Web suppriment les informations de fuseau horaire en appliquant une conversion en "Z" temps ulu (UTC) avant la sortie de la chaîne. Le fichier .toISOString () natif du navigateur supprime également les informations de fuseau horaire.

Cela supprime des informations précieuses, car le serveur ou le destinataire peut toujours convertir une date ISO complète en heure zoulou ou dans le fuseau horaire requis, tout en obtenant les informations de l'expéditeur.

La meilleure solution que j'ai trouvée est d'utiliser la bibliothèque javascript Moment.js et d'utiliser le code suivant:

Pour obtenir l'heure ISO actuelle avec les informations de fuseau horaire et les millisecondes

now = moment().format("YYYY-MM-DDTHH:mm:ss.SSSZZ")
// "2013-03-08T20:11:11.234+0100"

now = moment().utc().format("YYYY-MM-DDTHH:mm:ss.SSSZZ")
// "2013-03-08T19:11:11.234+0000"

now = moment().utc().format("YYYY-MM-DDTHH:mm:ss") + "Z"
// "2013-03-08T19:11:11Z" <- better use the native .toISOString() 

Pour obtenir l'heure ISO d'un objet Date JavaScript natif avec des informations sur le fuseau horaire mais sans millisecondes

var current_time = Date.now();
moment(current_time).format("YYYY-MM-DDTHH:mm:ssZZ")

Ceci peut être combiné avec Date.js pour obtenir des fonctions comme Date.today () dont le résultat peut ensuite être passé à l'instant.

Une chaîne de date ainsi formatée est un compilateur JSON et se prête bien à être stockée dans une base de données. Python et C # semblent l’aimer.

58
Daniel F

La question posée était format ISO avec précision réduite. Voila:

 new Date().toISOString().slice(0, 19) + 'Z'
 // '2014-10-23T13:18:06Z'

En supposant que le Z de fin est voulu, sinon omettez simplement.

24
arcseldon

Si vous n'avez pas besoin de supporter IE7, voici un excellent hack concis:

JSON.parse(JSON.stringify(new Date()))
12
Russell Davis

Le plus court, mais non pris en charge par Internet Explorer 8 et les versions antérieures:

new Date().toJSON()
11
younes0

En règle générale, je ne souhaite pas afficher de date UTC, car les clients n'aiment pas faire la conversion en tête. Pour afficher une date locale ISO, j'utilise la fonction:

function toLocalIsoString(date, includeSeconds) {
    function pad(n) { return n < 10 ? '0' + n : n }
    var localIsoString = date.getFullYear() + '-'
        + pad(date.getMonth() + 1) + '-'
        + pad(date.getDate()) + 'T'
        + pad(date.getHours()) + ':'
        + pad(date.getMinutes()) + ':'
        + pad(date.getSeconds());
    if(date.getTimezoneOffset() == 0) localIsoString += 'Z';
    return localIsoString;
};

La fonction ci-dessus omet les informations de décalage de fuseau horaire (sauf si l'heure locale est le temps UTC), j'utilise donc la fonction ci-dessous pour afficher le décalage local à un seul endroit. Vous pouvez également ajouter sa sortie aux résultats de la fonction ci-dessus si vous souhaitez afficher le décalage à chaque fois:

function getOffsetFromUTC() {
    var offset = new Date().getTimezoneOffset();
    return ((offset < 0 ? '+' : '-')
        + pad(Math.abs(offset / 60), 2)
        + ':'
        + pad(Math.abs(offset % 60), 2))
};

toLocalIsoString utilise pad. Si nécessaire, cela fonctionne comme n'importe quelle fonction de pad, mais par souci d'exhaustivité, voici ce que j'utilise:

// Pad a number to length using padChar
function pad(number, length, padChar) {
    if (typeof length === 'undefined') length = 2;
    if (typeof padChar === 'undefined') padChar = '0';
    var str = "" + number;
    while (str.length < length) {
        str = padChar + str;
    }
    return str;
}
6
Charles Burns

Le problème avec toISOString est qu’il donne la date/heure uniquement en tant que "Z". 

ISO-8601 définit également la date et l'heure avec une différence d'heure et de minute dans le fuseau horaire, sous les formes telles que 2016-07-16T19: 20h30 + 17h30 (lorsque le fuseau horaire est en avance sur l'heure UTC) et le 2016-07-16T19: 20: 30-01. : 00 (lorsque le fuseau horaire est derrière UTC).

Je ne pense pas que ce soit une bonne idée d'utiliser un autre plugin, moment.js pour une tâche aussi petite, en particulier lorsque vous pouvez l'obtenir avec quelques lignes de code.



    var timezone_offset_min = new Date().getTimezoneOffset(),
        offset_hrs = parseInt(Math.abs(timezone_offset_min/60)),
        offset_min = Math.abs(timezone_offset_min%60),
        timezone_standard;

    if(offset_hrs < 10)
        offset_hrs = '0' + offset_hrs;

    if(offset_min > 10)
        offset_min = '0' + offset_min;

    // getTimezoneOffset returns an offset which is positive if the local timezone is behind UTC and vice-versa.
    // So add an opposite sign to the offset
    // If offset is 0, it means timezone is UTC
    if(timezone_offset_min < 0)
        timezone_standard = '+' + offset_hrs + ':' + offset_min;
    else if(timezone_offset_min > 0)
        timezone_standard = '-' + offset_hrs + ':' + offset_min;
    else if(timezone_offset_min == 0)
        timezone_standard = 'Z';

    // Timezone difference in hours and minutes
    // String such as +5:30 or -6:00 or Z
    console.log(timezone_standard); 


Une fois le fuseau horaire décalé en heures et en minutes, vous pouvez ajouter une chaîne datetime.

J'ai écrit un article sur ce blog: http://usefulangle.com/post/30/javascript-get-date-time-with-offset-hours-minutes

3
Useful Angle
function timeStr(d) { 
  return ''+
    d.getFullYear()+
    ('0'+(d.getMonth()+1)).slice(-2)+
    ('0'+d.getDate()).slice(-2)+
    ('0'+d.getHours()).slice(-2)+
    ('0'+d.getMinutes()).slice(-2)+
    ('0'+d.getSeconds()).slice(-2);
}
3
Sean

Il manque un '+' après le 'T'

isoDate: function(msSinceEpoch) {
  var d = new Date(msSinceEpoch);
  return d.getUTCFullYear() + '-' + (d.getUTCMonth() + 1) + '-' + d.getUTCDate() + 'T'
         + d.getUTCHours() + ':' + d.getUTCMinutes() + ':' + d.getUTCSeconds();
}

devrait le faire.

Pour les zéros au début, vous pouvez utiliser ceci depuis ici :

function PadDigits(n, totalDigits) 
{ 
    n = n.toString(); 
    var pd = ''; 
    if (totalDigits > n.length) 
    { 
        for (i=0; i < (totalDigits-n.length); i++) 
        { 
            pd += '0'; 
        } 
    } 
    return pd + n.toString(); 
} 

En l'utilisant comme ceci:

PadDigits(d.getUTCHours(),2)
3
kaiz.net

Je voudrais juste utiliser cette petite extension à Date - http://blog.stevenlevithan.com/archives/date-time-format

var date = new Date(msSinceEpoch);
date.format("isoDateTime"); // 2007-06-09T17:46:21
2
Anurag

J'ai pu obtenir en dessous de la sortie avec très moins de code.

var ps = new Date('2010-04-02T14:12:07')  ;
ps = ps.toDateString() + " " + ps.getHours() + ":"+ ps.getMinutes() + " hrs";

Sortie:

Fri Apr 02 2010 19:42 hrs
2
Srikanth Srikanth
function getdatetime() {
    d = new Date();
    return (1e3-~d.getUTCMonth()*10+d.toUTCString()+1e3+d/1)
        .replace(/1(..)..*?(\d+)\D+(\d+).(\S+).*(...)/,'$3-$1-$2T$4.$5Z')
        .replace(/-(\d)T/,'-0$1T');
}

J'ai trouvé les bases de Stack Overflow quelque part (je crois que cela faisait partie d'un autre jeu de code Stack Exchange), et je l'ai amélioré pour qu'il fonctionne également sur Internet Explorer 10 ou une version antérieure. C'est moche, mais ça fait le travail.

0
Jonas Byström

Pour prolonger la réponse concise et concise de Sean avec du sucre et une syntaxe moderne:

// date.js

const getMonthName = (num) => {
  const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Oct', 'Nov', 'Dec'];
  return months[num];
};

const formatDate = (d) => {
  const date = new Date(d);
  const year = date.getFullYear();
  const month = getMonthName(date.getMonth());
  const day = ('0' + date.getDate()).slice(-2);
  const hour = ('0' + date.getHours()).slice(-2);
  const minutes = ('0' + date.getMinutes()).slice(-2);

  return `${year} ${month} ${day}, ${hour}:${minutes}`;
};

module.exports = formatDate;

Ensuite, par exemple.

import formatDate = require('./date');

const myDate = "2018-07-24T13:44:46.493Z"; // Actual value from wherever, eg. MongoDB date
console.log(formatDate(myDate)); // 2018 Jul 24, 13:44
0
Juha Untinen