370 votes

Comment formater le temps depuis xxx, par exemple "il y a 4 minutes", comme sur les sites Stack Exchange ?

La question est de savoir comment formater un fichier JavaScript Date comme une chaîne de caractères indiquant le temps écoulé, de la même manière que les temps affichés sur Stack Overflow.

par exemple

  • il y a 1 minute
  • il y a 1 heure
  • il y a 1 jour
  • il y a un mois
  • il y a 1 an

21 votes

6 votes

16 votes

482voto

Sky Sanders Points 19557
function timeSince(date) {

  var seconds = Math.floor((new Date() - date) / 1000);

  var interval = seconds / 31536000;

  if (interval > 1) {
    return Math.floor(interval) + " years";
  }
  interval = seconds / 2592000;
  if (interval > 1) {
    return Math.floor(interval) + " months";
  }
  interval = seconds / 86400;
  if (interval > 1) {
    return Math.floor(interval) + " days";
  }
  interval = seconds / 3600;
  if (interval > 1) {
    return Math.floor(interval) + " hours";
  }
  interval = seconds / 60;
  if (interval > 1) {
    return Math.floor(interval) + " minutes";
  }
  return Math.floor(seconds) + " seconds";
}
var aDay = 24*60*60*1000;
console.log(timeSince(new Date(Date.now()-aDay)));
console.log(timeSince(new Date(Date.now()-aDay*2)));

3 votes

@hello - oui, le point de sortie unique a ses vertus quand il ne gêne pas. ceux qui le prennent trop au sérieux de nos jours comprennent mal l'origine de la maxime.

53 votes

Bonne fonction, mais quelques remarques. J'ai changé la première ligne en : var seconds = Math.floor(((new Date().getTime()/1000) - date)) pour travailler avec les timestamps unix. Et j'ai eu besoin de changer l'intval > 1 en intval >=1, sinon cela affichait des choses comme 75 minutes (entre 1 et 2 heures).

3 votes

@PanMan si vous changez simplement > en >= alors vous vous retrouverez avec des temps comme "1 minutes". J'ai posté une version modifiée de cette réponse qui ajoute le "s" de manière conditionnelle : stackoverflow.com/a/23259289/373655

204voto

Fabiano PS Points 1598

C'est peut-être un peu exagéré dans ce cas, mais si l'occasion se présente moment.js est tout simplement génial !

Moment.js est une bibliothèque javascript de datetime, pour l'utiliser dans un tel scénario, il faut faire :

moment(yourdate).fromNow()

http://momentjs.com/docs/#/displaying/fromnow/

Addendum 2018 : Luxon est une nouvelle bibliothèque moderne qui vaut peut-être le coup d'œil !

0 votes

Qu'est-ce que je peux faire si je n'ai besoin que des premières lettres des données, comme l'année pour y, le mois pour m et le jour pour d ?

0 votes

Comment puis-je obtenir seulement des jours et non des mois en utilisant cette méthode ?

82voto

TheBrain Points 2474

Cette fonction vous permet d'afficher des formats de temps passés et précédents tels que "il y a 2 jours", "dans 10 minutes". Vous pouvez lui transmettre un objet Date, un horodatage numérique ou une chaîne de date.

function time_ago(time) {

  switch (typeof time) {
    case 'number':
      break;
    case 'string':
      time = +new Date(time);
      break;
    case 'object':
      if (time.constructor === Date) time = time.getTime();
      break;
    default:
      time = +new Date();
  }
  var time_formats = [
    [60, 'seconds', 1], // 60
    [120, '1 minute ago', '1 minute from now'], // 60*2
    [3600, 'minutes', 60], // 60*60, 60
    [7200, '1 hour ago', '1 hour from now'], // 60*60*2
    [86400, 'hours', 3600], // 60*60*24, 60*60
    [172800, 'Yesterday', 'Tomorrow'], // 60*60*24*2
    [604800, 'days', 86400], // 60*60*24*7, 60*60*24
    [1209600, 'Last week', 'Next week'], // 60*60*24*7*4*2
    [2419200, 'weeks', 604800], // 60*60*24*7*4, 60*60*24*7
    [4838400, 'Last month', 'Next month'], // 60*60*24*7*4*2
    [29030400, 'months', 2419200], // 60*60*24*7*4*12, 60*60*24*7*4
    [58060800, 'Last year', 'Next year'], // 60*60*24*7*4*12*2
    [2903040000, 'years', 29030400], // 60*60*24*7*4*12*100, 60*60*24*7*4*12
    [5806080000, 'Last century', 'Next century'], // 60*60*24*7*4*12*100*2
    [58060800000, 'centuries', 2903040000] // 60*60*24*7*4*12*100*20, 60*60*24*7*4*12*100
  ];
  var seconds = (+new Date() - time) / 1000,
    token = 'ago',
    list_choice = 1;

  if (seconds == 0) {
    return 'Just now'
  }
  if (seconds < 0) {
    seconds = Math.abs(seconds);
    token = 'from now';
    list_choice = 2;
  }
  var i = 0,
    format;
  while (format = time_formats[i++])
    if (seconds < format[0]) {
      if (typeof format[2] == 'string')
        return format[list_choice];
      else
        return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token;
    }
  return time;
}

var aDay = 24 * 60 * 60 * 1000;
console.log(time_ago(new Date(Date.now() - aDay)));
console.log(time_ago(new Date(Date.now() - aDay * 2)));

0 votes

Remplacer la dernière ligne return time; con format = time_formats[time_formats.length - 1]; return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token; pour renvoyer des siècles pour les grandes périodes de temps au lieu des millisecondes.

1 votes

Très bien ! Cependant, j'ai remarqué que dans iOS, lorsqu'il est utilisé avec angular comme un filtre, le navigateur renvoie NaN ici. Ceci le corrige : time = +new Date(time.replace(/-/g, '/')) ;

0 votes

Super, mais l'affectation dans cette boucle est moche et déroutante. Il vaudrait mieux changer pour une boucle forEach.

60voto

Maxim Zaslavsky Points 6873

Je n'ai pas vérifié (bien que ce ne serait pas difficile), mais je pense que Les sites Stack Exchange utilisent le jquery.timeago plugin pour créer ces chaînes de temps .


Le plugin est assez facile à utiliser, il est propre et se met à jour automatiquement.

Voici un échantillon rapide (de la page d'accueil du plugin) :

Tout d'abord, chargez jQuery et le plugin :

<script src="jquery.min.js" type="text/javascript"></script> <script src="jquery.timeago.js" type="text/javascript"></script>

Maintenant, attachons-le à votre timestamps sur DOM ready :

jQuery(document).ready(function() { jQuery("abbr.timeago").timeago(); });

Cela va transformer tous les abbr éléments avec une classe de timeago et un ISO 8601 dans le titre : <abbr class="timeago" title="2008-07-17T09:24:17Z">July 17, 2008</abbr> en quelque chose comme ça : <abbr class="timeago" title="July 17, 2008">about a year ago</abbr> qui donne : il y a environ un an. Au fur et à mesure que le temps le temps passe, les horodateurs seront automatiquement mis à jour.

19 votes

Tout le monde n'utilise pas JQuery.

4 votes

Cela n'a aucun sens de l'avoir en tant que plugin jquery.

15voto

PanMan Points 461

J'ai changé la fonction ci-dessus en

function timeSince(date) {

    var seconds = Math.floor(((new Date().getTime()/1000) - date)),
    interval = Math.floor(seconds / 31536000);

    if (interval > 1) return interval + "y";

    interval = Math.floor(seconds / 2592000);
    if (interval > 1) return interval + "m";

    interval = Math.floor(seconds / 86400);
    if (interval >= 1) return interval + "d";

    interval = Math.floor(seconds / 3600);
    if (interval >= 1) return interval + "h";

    interval = Math.floor(seconds / 60);
    if (interval > 1) return interval + "m ";

    return Math.floor(seconds) + "s";
}

Sinon, il afficherait des choses comme "75 minutes" (entre 1 et 2 heures). Il suppose également que la date d'entrée est un timestamp Unix.

0 votes

Divisez la date par 1000 s'il vous plaît.

0 votes

Je l'ai utilisé lorsque les données provenaient d'une base de données avec des timestamps Unix en secondes. Lorsqu'il s'agit de millisecondes, il faut diviser par 1000.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X