Comment formater l'heure depuis xxx, par exemple «il y a 4 minutes», similaire aux sites Stack Exchange


210

La question est de savoir comment formater un JavaScript en Datetant que chaîne indiquant le temps écoulé de la même manière que vous voyez les temps affichés sur Stack Overflow.

par exemple

  • il y a 1 minute
  • Il ya 1 heure
  • il y a 1 jour
  • Il ya 1 mois
  • il y a 1 an



Réponses:


324

function timeSince(date) {

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

  var interval = Math.floor(seconds / 31536000);

  if (interval > 1) {
    return interval + " years";
  }
  interval = Math.floor(seconds / 2592000);
  if (interval > 1) {
    return interval + " months";
  }
  interval = Math.floor(seconds / 86400);
  if (interval > 1) {
    return interval + " days";
  }
  interval = Math.floor(seconds / 3600);
  if (interval > 1) {
    return interval + " hours";
  }
  interval = Math.floor(seconds / 60);
  if (interval > 1) {
    return 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
@hello - oui, un point de sortie unique a ses vertus quand il ne gêne pas. ceux qui la prennent trop au sérieux de nos jours se méprennent sur l'origine de la maxime.
Sky Sanders

36
Bon fonctionnement, mais quelques remarques. Modification de la première ligne en: var seconds = Math.floor (((new Date (). GetTime () / 1000) - date)) pour fonctionner avec les horodatages Unix. Et nécessaire de changer l'intval> 1 en intval> = 1 sinon cela montrerait des choses comme 75 minutes (entre 1 et 2 heures).
PanMan

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

N'utilisez jamais la concaténation de chaînes, mais String.format si vous voulez une solution qui peut être internationalisée
rds

Et si je veux le placer en classe div? Que puis-je faire? Désolé, je ne suis pas un pro en javascript. J'ai essayé ce document.getElementsByTagName ('. Sampleclass') [0] .innerHTML = timeSince (date); et ce document.getElementById ('idname') [0] .innerHTML = timeSince (date); mais ça ne marche pas. De l'aide? Je vous remercie.
x'tian

119

Cela peut être 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 datetime javascript, pour l'utiliser pour un tel scénario, vous feriez:

moment(yourdate).fromNow()

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

Addendum 2018 : Luxon est une nouvelle bibliothèque moderne et pourrait valoir le coup d'œil!


Bonjour, j'utilise votre réponse pour obtenir une différence de temps. Que puis-je faire si je n'ai besoin que des premières lettres d'une année semblable à une date comme y, mois et m et jour comme d?
Nodirabegimxonoyim

57

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


Il est assez facile d'utiliser le plugin, il est propre et se met à jour automatiquement.

Voici un exemple 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 à vos horodatages sur DOM ready:

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

Cela transformera tous les abbréléments avec une classe de timeagoet un horodatage ISO 8601 dans le titre: <abbr class="timeago" title="2008-07-17T09:24:17Z">July 17, 2008</abbr>en quelque chose comme ceci: <abbr class="timeago" title="July 17, 2008">about a year ago</abbr>qui donne: il y a environ un an. Au fil du temps, les horodatages seront automatiquement mis à jour.


11
Tout le monde n'utilise pas JQuery.

2
Cela n'a aucun sens d'avoir ceci en tant que plugin jquery.
AlexG

57

Cela vous montrera les formats d'heure passés et précédents comme 'il y a 2 jours' 'dans 10 minutes' et vous pouvez lui passer soit 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)));


Remplacez la dernière ligne return time;par format = time_formats[time_formats.length - 1]; return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token;pour renvoyer des siècles pendant de longues périodes au lieu des millisecondes.
Aquila Sands

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

Super, mais l'affectation dans cette boucle while est moche et déroutante. Il serait préférable de passer à une boucle forEach
Martin Dawson

25

Voici une légère modification de la solution de Sky Sander qui permet de saisir la date sous forme de chaîne et est capable d'afficher des plages telles que "1 minute" au lieu de "73 secondes"

var timeSince = function(date) {
  if (typeof date !== 'object') {
    date = new Date(date);
  }

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

  var interval = Math.floor(seconds / 31536000);
  if (interval >= 1) {
    intervalType = 'year';
  } else {
    interval = Math.floor(seconds / 2592000);
    if (interval >= 1) {
      intervalType = 'month';
    } else {
      interval = Math.floor(seconds / 86400);
      if (interval >= 1) {
        intervalType = 'day';
      } else {
        interval = Math.floor(seconds / 3600);
        if (interval >= 1) {
          intervalType = "hour";
        } else {
          interval = Math.floor(seconds / 60);
          if (interval >= 1) {
            intervalType = "minute";
          } else {
            interval = seconds;
            intervalType = "second";
          }
        }
      }
    }
  }

  if (interval > 1 || interval === 0) {
    intervalType += 's';
  }

  return interval + ' ' + intervalType;
};
var aDay = 24 * 60 * 60 * 1000;
console.log(timeSince(new Date(Date.now() - aDay)));
console.log(timeSince(new Date(Date.now() - aDay * 2)));


2
Cela ne fonctionne pas pendant quelques secondes car l'intervalle est laissé à 0 à partir de interval = Math.floor(seconds / 60);. J'ai ajouté interval = seconds;dans la finale elseet ça marche bien.
howard10

2
Si l'intervalle est 0, vous devez également ajouter le "s".
JW.

C'est génial. Pour TS, j'ai dû ajouter un opérateur unairelet seconds = Math.floor((+new Date() - date) / 1000);
Ben Racicot

Pourquoi vérifiez-vous même pour interval === 0le dernier if?
smartmouse

1
@smartmouse pour qu'il dise "0 seconde" au lieu de "0 seconde"
rob

14

Vous voudrez peut-être regarder humanized_time_span: https://github.com/layam/js_humanized_time_span

C'est un cadre indépendant et entièrement personnalisable.

Il suffit de télécharger / inclure le script et vous pouvez alors faire ceci:

humanized_time_span("2011-05-11 12:00:00")  
   => '3 hours ago'

humanized_time_span("2011-05-11 12:00:00", "2011-05-11 16:00:00)  
   => '4 hours ago'

ou même ceci:

var custom_date_formats = {
  past: [
    { ceiling: 60, text: "less than a minute ago" },
    { ceiling: 86400, text: "$hours hours, $minutes minutes and $seconds seconds ago" },
    { ceiling: null, text: "$years years ago" }
  ],
  future: [
    { ceiling: 60, text: "in less than a minute" },
    { ceiling: 86400, text: "in $hours hours, $minutes minutes and $seconds seconds time" },
    { ceiling: null, text: "in $years years" }
  ]
}

humanized_time_span("2010/09/10 10:00:00", "2010/09/10 10:00:05", custom_date_formats) 
  => "less than a minute ago"

Lisez les documents pour plus d'informations.


4
Cela signifie simplement qu'il ne repose pas sur jQuery ou même sur un DOM.
Will Tomlins

Ça me donne NaN years agopourquoi ??

sacrément je l'ai eu ... votre exemple de son utilisation est faux. vous délimitez réellement les premiers nombres avec une barre oblique plutôt que "-" .. comme cecihumanized_time_span("2011/05/11 12:00:00")

cela peut dépendre de votre culture locale et différer d'un utilisateur à l'autre :)
mikus

13

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, cela montrerait des choses comme "75 minutes" (entre 1 et 2 heures). Il suppose également maintenant que la date d'entrée est un horodatage Unix.


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

J'ai utilisé cela où les données provenaient d'une base de données avec des horodatages Unix en quelques secondes. Quand il est en millisecondes, vous devez diviser par 1000.
PanMan

11

Code très lisible et compatible avec tous les navigateurs:

Tel que donné par @Travis

var DURATION_IN_SECONDS = {
  epochs: ['year', 'month', 'day', 'hour', 'minute'],
  year: 31536000,
  month: 2592000,
  day: 86400,
  hour: 3600,
  minute: 60
};

function getDuration(seconds) {
  var epoch, interval;

  for (var i = 0; i < DURATION_IN_SECONDS.epochs.length; i++) {
    epoch = DURATION_IN_SECONDS.epochs[i];
    interval = Math.floor(seconds / DURATION_IN_SECONDS[epoch]);
    if (interval >= 1) {
      return {
        interval: interval,
        epoch: epoch
      };
    }
  }

};

function timeSince(date) {
  var seconds = Math.floor((new Date() - new Date(date)) / 1000);
  var duration = getDuration(seconds);
  var suffix = (duration.interval > 1 || duration.interval === 0) ? 's' : '';
  return duration.interval + ' ' + duration.epoch + suffix;
};

alert(timeSince('2015-09-17T18:53:23'));


Notez que cela fait des hypothèses erronées, comme chaque jour étant de 86 400 secondes (sauf si le fuseau horaire est réglé sur UTC, ce n'est pas toujours vrai grâce à UTC)
ItalyPaleAle

10

Une version plus courte utilisée par Lokely :

const intervals = [
  { label: 'year', seconds: 31536000 },
  { label: 'month', seconds: 2592000 },
  { label: 'day', seconds: 86400 },
  { label: 'hour', seconds: 3600 },
  { label: 'minute', seconds: 60 },
  { label: 'second', seconds: 0 }
];

function timeSince(date) {
  const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
  const interval = intervals.find(i => i.seconds < seconds);
  const count = Math.floor(seconds / interval.seconds);
  return `${count} ${interval.label}${count !== 1 ? 's' : ''} ago`;
}

2
L'intervalle le plus court a une durée de zéro seconde - il en résulte une division par zéro erreur.
apk

@apk a raison. <60 secondes, il imprimeInfinity seconds ago
leonheess

8

à partir de maintenant, param horodatage unix,

function timeSince(ts){
    now = new Date();
    ts = new Date(ts*1000);
    var delta = now.getTime() - ts.getTime();

    delta = delta/1000; //us to s

    var ps, pm, ph, pd, min, hou, sec, days;

    if(delta<=59){
        ps = (delta>1) ? "s": "";
        return delta+" second"+ps
    }

    if(delta>=60 && delta<=3599){
        min = Math.floor(delta/60);
        sec = delta-(min*60);
        pm = (min>1) ? "s": "";
        ps = (sec>1) ? "s": "";
        return min+" minute"+pm+" "+sec+" second"+ps;
    }

    if(delta>=3600 && delta<=86399){
        hou = Math.floor(delta/3600);
        min = Math.floor((delta-(hou*3600))/60);
        ph = (hou>1) ? "s": "";
        pm = (min>1) ? "s": "";
        return hou+" hour"+ph+" "+min+" minute"+pm;
    } 

    if(delta>=86400){
        days = Math.floor(delta/86400);
        hou =  Math.floor((delta-(days*86400))/60/60);
        pd = (days>1) ? "s": "";
        ph = (hou>1) ? "s": "";
        return days+" day"+pd+" "+hou+" hour"+ph;
    }

}

5

Une version ES6 du code fourni par @ user1012181

// Epochs
const epochs = [
    ['year', 31536000],
    ['month', 2592000],
    ['day', 86400],
    ['hour', 3600],
    ['minute', 60],
    ['second', 1]
];


// Get duration
const getDuration = (timeAgoInSeconds) => {
    for (let [name, seconds] of epochs) {
        const interval = Math.floor(timeAgoInSeconds / seconds);

        if (interval >= 1) {
            return {
                interval: interval,
                epoch: name
            };
        }
    }
};


// Calculate
const timeAgo = (date) => {
    const timeAgoInSeconds = Math.floor((new Date() - new Date(date)) / 1000);
    const {interval, epoch} = getDuration(timeAgoInSeconds);
    const suffix = interval === 1 ? '' : 's';

    return `${interval} ${epoch}${suffix} ago`;
};

Édité avec des suggestions @ ibe-vanmeenen. (Merci !)


Vous devez également inclure "second: 1" dans EPOCHS, sinon il se cassera s'il y a moins d'une minute :). Les 3 derniers vars pourraient également être un non constant?
Ibe Vanmeenen

1
De plus, EPOCHS doit être un tableau, car les objets ne garantissent pas l'ordre des propriétés. J'ai enregistré mes modifications dans gist.github.com/IbeVanmeenen/4e3e58820c9168806e57530563612886 . Vous pouvez les copier pour modifier cette réponse :)
Ibe Vanmeenen

5

Version simple et lisible:

const NOW = new Date()
const times = [["second", 1], ["minute", 60], ["hour", 3600], ["day", 86400], ["week", 604800], ["month", 2592000], ["year", 31536000]]

function timeAgo(date) {
    var diff = Math.round((NOW - date) / 1000)
    for (var t = 0; t < times.length; t++) {
        if (diff < times[t][1]) {
            if (t == 0) {
                return "Just now"
            } else {
                diff = Math.round(diff / times[t - 1][1])
                return diff + " " + times[t - 1][0] + (diff == 1?" ago":"s ago")
            }
        }
    }
}

3

J'en écris un avec js et python, utilisé dans deux projets, très agréable et simple: une simple bibliothèque (moins de 2 Ko) utilisée pour formater la date avec la *** time agodéclaration.

simple, petit, facile à utiliser et bien testé.

  1. npm install timeago.js

  2. import timeago from 'timeago.js'; // or use script tag

  3. utilisez l'api format.

Échantillon:

var timeagoIns  = timeago();
timeagoIns .format('2016-06-12');

Vous pouvez également effectuer un rendu en temps réel.

var timeagoIns = timeago();
timeagoIns.render(document.querySelectorAll('time'));

Depuis 4.0, vous pouvez utiliser une importation déstructurée à la place:import { format, render, cancel, register } from 'timeago.js';
cmfolio

3

Bien que la question ait été posée il y a assez longtemps, écrire cette réponse avec espoir aidera quelqu'un.

Passez la date à partir de laquelle vous souhaitez commencer à compter. Utilisation moment().fromNow()de momentjs : (Voir plus d'informations ici )

getRelativeTime(date) {
    const d = new Date(date * 1000);
    return moment(d).fromNow();
}

Si vous souhaitez modifier les informations fournies pour les dates à partir de Maintenant, vous écrivez votre heure relative personnalisée pour le moment.

Par exemple, dans mon propre cas, je voulais imprimer 'one month ago'au lieu de 'a month ago'( fourni par moment (d) .fromNow () ). Dans ce cas, vous pouvez écrire quelque chose ci-dessous.

moment.updateLocale('en', {
    relativeTime: {
        future: 'in %s',
        past: '%s ago',
        s: 'a few seconds',
        ss: '%d seconds',
        m: '1 m',
        mm: '%d minutes',
        h: '1 h',
        hh: '%d hours',
        d: '1 d',
        dd: '%d days',
        M: '1 month',
        MM: '%d months',
        y: '1 y',
        yy: '%d years'
    }
});

REMARQUE : j'ai écrit mon code de projet dans Agular 6


3

Peut également utiliser le plugin dayjs relativeTime pour résoudre ce problème.

import * as dayjs from 'dayjs';
import * as relativeTime from 'dayjs/plugin/relativeTime';

dayjs.extend(relativeTime);
dayjs(dayjs('1990')).fromNow(); // x years ago

3

Cela devrait gérer correctement tout horodatage valide, y compris Date.now (), les unités singulières et les dates futures. J'ai omis des mois, mais ceux-ci devraient être faciles à ajouter. J'ai essayé de le garder aussi lisible que possible.

function getTimeInterval(date) {
  let seconds = Math.floor((Date.now() - date) / 1000);
  let unit = "second";
  let direction = "ago";
  if (seconds < 0) {
    seconds = -seconds;
    direction = "from now";
  }
  let value = seconds;
  if (seconds >= 31536000) {
    value = Math.floor(seconds / 31536000);
    unit = "year";
  } else if (seconds >= 86400) {
    value = Math.floor(seconds / 86400);
    unit = "day";
  } else if (seconds >= 3600) {
    value = Math.floor(seconds / 3600);
    unit = "hour";
  } else if (seconds >= 60) {
    value = Math.floor(seconds / 60);
    unit = "minute";
  }
  if (value != 1)
    unit = unit + "s";
  return value + " " + unit + " " + direction;
}

console.log(getTimeInterval(Date.now())); // 0 seconds ago
console.log(getTimeInterval(Date.now() + 1000)); // 1 second from now
console.log(getTimeInterval(Date.now() - 1000)); // 1 second ago
console.log(getTimeInterval(Date.now() + 60000)); // 1 minute from now
console.log(getTimeInterval(Date.now() - 120000)); // 2 minutes ago
console.log(getTimeInterval(Date.now() + 120000)); // 2 minutes from now
console.log(getTimeInterval(Date.now() + 3600000)); // 1 hour from now
console.log(getTimeInterval(Date.now() + 360000000000)); // 11 years from now
console.log(getTimeInterval(0)); // 49 years ago


2

J'ai modifié la version de Sky Sanders. Les opérations Math.floor (...) sont évaluées dans le bloc if

       var timeSince = function(date) {
            var seconds = Math.floor((new Date() - date) / 1000);
            var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
            if (seconds < 5){
                return "just now";
            }else if (seconds < 60){
                return seconds + " seconds ago";
            }
            else if (seconds < 3600) {
                minutes = Math.floor(seconds/60)
                if(minutes > 1)
                    return minutes + " minutes ago";
                else
                    return "1 minute ago";
            }
            else if (seconds < 86400) {
                hours = Math.floor(seconds/3600)
                if(hours > 1)
                    return hours + " hours ago";
                else
                    return "1 hour ago";
            }
            //2 days and no more
            else if (seconds < 172800) {
                days = Math.floor(seconds/86400)
                if(days > 1)
                    return days + " days ago";
                else
                    return "1 day ago";
            }
            else{

                //return new Date(time).toLocaleDateString();
                return date.getDate().toString() + " " + months[date.getMonth()] + ", " + date.getFullYear();
            }
        }

il y a une faute de frappe dans le dernier autre si cela return days + "1 day ago";devrait êtrereturn "1 day ago";
Marco Gurnari

2
function dateToHowManyAgo(stringDate){
    var currDate = new Date();
    var diffMs=currDate.getTime() - new Date(stringDate).getTime();
    var sec=diffMs/1000;
    if(sec<60)
        return parseInt(sec)+' second'+(parseInt(sec)>1?'s':'')+' ago';
    var min=sec/60;
    if(min<60)
        return parseInt(min)+' minute'+(parseInt(min)>1?'s':'')+' ago';
    var h=min/60;
    if(h<24)
        return parseInt(h)+' hour'+(parseInt(h)>1?'s':'')+' ago';
    var d=h/24;
    if(d<30)
        return parseInt(d)+' day'+(parseInt(d)>1?'s':'')+' ago';
    var m=d/30;
    if(m<12)
        return parseInt(m)+' month'+(parseInt(m)>1?'s':'')+' ago';
    var y=m/12;
    return parseInt(y)+' year'+(parseInt(y)>1?'s':'')+' ago';
}
console.log(dateToHowManyAgo('2019-11-07 19:17:06'));

1
function timeago(date) {
    var seconds = Math.floor((new Date() - date) / 1000);
    if(Math.round(seconds/(60*60*24*365.25)) >= 2) return Math.round(seconds/(60*60*24*365.25)) + " years ago";
    else if(Math.round(seconds/(60*60*24*365.25)) >= 1) return "1 year ago";
    else if(Math.round(seconds/(60*60*24*30.4)) >= 2) return Math.round(seconds/(60*60*24*30.4)) + " months ago";
    else if(Math.round(seconds/(60*60*24*30.4)) >= 1) return "1 month ago";
    else if(Math.round(seconds/(60*60*24*7)) >= 2) return Math.round(seconds/(60*60*24*7)) + " weeks ago";
    else if(Math.round(seconds/(60*60*24*7)) >= 1) return "1 week ago";
    else if(Math.round(seconds/(60*60*24)) >= 2) return Math.round(seconds/(60*60*24)) + " days ago";
    else if(Math.round(seconds/(60*60*24)) >= 1) return "1 day ago";
    else if(Math.round(seconds/(60*60)) >= 2) return Math.round(seconds/(60*60)) + " hours ago";
    else if(Math.round(seconds/(60*60)) >= 1) return "1 hour ago";
    else if(Math.round(seconds/60) >= 2) return Math.round(seconds/60) + " minutes ago";
    else if(Math.round(seconds/60) >= 1) return "1 minute ago";
    else if(seconds >= 2)return seconds + " seconds ago";
    else return seconds + "1 second ago";
}

1

Ma solution ..

(function(global){
            const SECOND   = 1;
            const MINUTE   = 60;
            const HOUR     = 3600;
            const DAY      = 86400;
            const MONTH    = 2629746;
            const YEAR     = 31556952;
            const DECADE   = 315569520;

            global.timeAgo = function(date){
                var now = new Date();
                var diff = Math.round(( now - date ) / 1000);

                var unit = '';
                var num = 0;
                var plural = false;

                switch(true){
                    case diff <= 0:
                        return 'just now';
                    break;

                    case diff < MINUTE:
                        num = Math.round(diff / SECOND);
                        unit = 'sec';
                        plural = num > 1;
                    break;

                    case diff < HOUR:
                        num = Math.round(diff / MINUTE);
                        unit = 'min';
                        plural = num > 1;
                    break;

                    case diff < DAY:
                        num = Math.round(diff / HOUR);
                        unit = 'hour';
                        plural = num > 1;
                    break;

                    case diff < MONTH:
                        num = Math.round(diff / DAY);
                        unit = 'day';
                        plural = num > 1;
                    break;

                    case diff < YEAR:
                        num = Math.round(diff / MONTH);
                        unit = 'month';
                        plural = num > 1;
                    break;

                    case diff < DECADE:
                        num = Math.round(diff / YEAR);
                        unit = 'year';
                        plural = num > 1;
                    break;

                    default:
                        num = Math.round(diff / YEAR);
                        unit = 'year';
                        plural = num > 1;
                }

                var str = '';
                if(num){
                    str += `${num} `;
                }

                str += `${unit}`;

                if(plural){
                    str += 's';
                }

                str += ' ago';

                return str;
            }
        })(window);

        console.log(timeAgo(new Date()));
        console.log(timeAgo(new Date('Jun 03 2018 15:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('Jun 03 2018 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('May 28 2018 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('May 28 2017 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('May 28 2000 13:12:19 GMT+0300 (FLE Daylight Time)')));
        console.log(timeAgo(new Date('Sep 10 1994 13:12:19 GMT+0300 (FLE Daylight Time)')));

1

Mon coup de poignard à cela basé sur d'autres réponses.

function timeSince(date) {
    let minute = 60;
    let hour   = minute * 60;
    let day    = hour   * 24;
    let month  = day    * 30;
    let year   = day    * 365;

    let suffix = ' ago';

    let elapsed = Math.floor((Date.now() - date) / 1000);

    if (elapsed < minute) {
        return 'just now';
    }

    // get an array in the form of [number, string]
    let a = elapsed < hour  && [Math.floor(elapsed / minute), 'minute'] ||
            elapsed < day   && [Math.floor(elapsed / hour), 'hour']     ||
            elapsed < month && [Math.floor(elapsed / day), 'day']       ||
            elapsed < year  && [Math.floor(elapsed / month), 'month']   ||
            [Math.floor(elapsed / year), 'year'];

    // pluralise and append suffix
    return a[0] + ' ' + a[1] + (a[0] === 1 ? '' : 's') + suffix;
}

0

Je cherchais une réponse à cela et j'ai presque mis en œuvre l'une de ces solutions, mais un collègue m'a rappelé de vérifier la react-intlbibliothèque car nous l'utilisions déjà.

Donc, en ajoutant aux solutions ... dans le cas où vous utilisez la react-intlbibliothèque, ils ont un <FormattedRelative>composant pour cela.

https://github.com/yahoo/react-intl/wiki/Components#formattedrelative


0

Voici ce que j'ai fait (l'objet renvoie l'unité de temps avec sa valeur):

function timeSince(post_date, reference)
{
	var reference = reference ? new Date(reference) : new Date(),
		diff = reference - new Date(post_date + ' GMT-0000'),
		date = new Date(diff),
		object = { unit: null, value: null };
	
	if (diff < 86400000)
	{
		var secs  = date.getSeconds(),
			mins  = date.getMinutes(),
			hours = date.getHours(),
			array = [ ['second', secs], ['minute', mins], ['hour', hours] ];
	}
	else
	{
		var days   = date.getDate(),
			weeks  = Math.floor(days / 7),
			months = date.getMonth(),
			years  = date.getFullYear() - 1970,
			array  = [ ['day', days], ['week', weeks], ['month', months], ['year', years] ];
	}

	for (var i = 0; i < array.length; i++)
	{
		array[i][0] += array[i][1] != 1 ? 's' : '';

		object.unit  = array[i][1] >= 1 ? array[i][0] : object.unit;
		object.value = array[i][1] >= 1 ? array[i][1] : object.value;
	}

	return object;
}

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.