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
Sky Sanders
la source
14
momentjs.com
atilkan
Utile pour cela: Intl.RelativeTimeFormat.prototype.format().
Константин Ван

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)));

Sky Sanders
la source
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!

Fabiano Soriani
la source
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.

Maxim Zaslavsky
la source
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)));

Le cerveau
la source
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)));

Rob
la source
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.

Will Tomlins
la source
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.

PanMan
la source
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'));

user1012181
la source
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`;
}
Sam
la source
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;
    }

}
pkarc
la source
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 !)

Geoffroy Warin
la source
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")
            }
        }
    }
}
jcrs
la source
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'));
un outil
la source
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

Nodirabegimxonoyim
la source
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
jjbskir
la source
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

Volonté
la source
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();
            }
        }
Moses Koledoye
la source
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'));
Boumeziane Marouane
la source
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";
}
Uygar
la source
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)')));
nikksan
la source
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;
}
Maksim Ivanov
la source
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

ewH
la source
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;
}

nateclonch
la source