Come formattare il tempo dal xxx, ad es. "4 minuti fa" simile ai siti Stack Exchange


210

La domanda è come formattare un JavaScript Datecome una stringa indicando il tempo trascorso simile al modo in cui vedi i tempi visualizzati su Stack Overflow.

per esempio

  • 1 minuto fa
  • 1 ora fa
  • 1 giorno fa
  • 1 mese fa
  • 1 anno fa



Risposte:


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
@ Ciao - Sì, il singolo punto di uscita ha le sue virtù quando non si mette in mezzo. quelli che lo prendono troppo sul serio in questi giorni stanno fraintendendo l'origine della massima.
Sky Sanders,

36
Buona funzione, ma alcune osservazioni. Modificata la prima riga in: var seconds = Math.floor (((new Date (). GetTime () / 1000) - date)) per funzionare con i timestamp unix. E necessario cambiare intval> 1 in intval> = 1 altrimenti mostrerebbe cose come 75 minuti (tra 1 e 2 ore).
PanMan,

3
@PanMan se cambi>>> = finirai con tempi come "1 minuti". Ho pubblicato una versione modificata di questa risposta che aggiunge condizionatamente la "s": stackoverflow.com/a/23259289/373655
rob

Non utilizzare mai la concatenazione di stringhe, ma String.format se si desidera una soluzione che può essere internazionalizzata
rds

E se volessi inserirlo nella classe div? Cosa posso fare? Mi dispiace non sono un professionista in JavaScript. Ho provato questo document.getElementsByTagName ('. Sampleclass') [0] .innerHTML = timeSince (date); e questo document.getElementById ('idname') [0] .innerHTML = timeSince (data); ma non funziona. Qualsiasi aiuto? Grazie.
x'tian,

119

Potrebbe essere un problema in questo caso, ma se l'opportunità mostra moment.js è semplicemente fantastico!

Moment.js è una libreria datetime javascript, per usarlo per tale scenario, devi fare:

moment(yourdate).fromNow()

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

Addendum 2018 : Luxon è una nuova biblioteca moderna e potrebbe valere la pena dare un'occhiata!


Ciao, sto usando la tua risposta per ottenere differenze di tempo. Cosa posso fare se ho bisogno solo delle prime lettere dell'anno come data, mese, mese e giorno come d?
Nodirabegimxonoyim,

57

Non ho controllato (anche se non sarebbe difficile), ma penso che i siti Stack Exchange utilizzino il jquery.timeagoplug-in per creare queste stringhe di tempo .


È abbastanza facile usare il plugin, è pulito e si aggiorna automaticamente.

Ecco un breve esempio (dalla home page del plugin):

Innanzitutto, carica jQuery e il plug-in:

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

Ora, alleghiamo i timestamp su DOM ready:

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

Ciò trasformerà tutti gli abbrelementi con una classe timeagoe un timestamp ISO 8601 nel titolo: <abbr class="timeago" title="2008-07-17T09:24:17Z">July 17, 2008</abbr>in qualcosa del genere: <abbr class="timeago" title="July 17, 2008">about a year ago</abbr>che produce: circa un anno fa. Col passare del tempo, i timestamp si aggiorneranno automaticamente.


11
Non tutti usano JQuery.

2
Non ha senso avere questo come plugin jquery.
AlexG

57

Questo ti mostrerà i formati di tempo passati e precedenti come '2 giorni fa' '10 minuti da adesso' e puoi passarlo sia un oggetto Date, un timestamp numerico o una stringa di data

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


Sostituisci l'ultima riga return time;con format = time_formats[time_formats.length - 1]; return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token;per tornare indietro di secoli per grandi intervalli di tempo anziché i millisecondi.
Aquila Sands,

Molto bella! Anche se ho notato in iOS, quando usato con angolare come filtro, il browser restituisce NaN qui. Questo lo risolve: time = + new Date (time.replace (/ - / g, '/'));
Tiago,

Fantastico, ma il compito in quel ciclo while è brutto e confuso. Passare a un ciclo per ogni sarebbe meglio
Martin Dawson

25

Ecco una leggera modifica sulla soluzione di Sky Sander che consente di inserire la data come stringa ed è in grado di visualizzare intervalli come "1 minuto" anziché "73 secondi"

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
Questo non funziona per secondi poiché l'intervallo viene lasciato come 0 da interval = Math.floor(seconds / 60);. Ho aggiunto interval = seconds;alla finale elsee funziona benissimo.
howard10

2
Se l'intervallo è 0, dovresti anche aggiungere la "s".
JW.

Questo e spettacolare. Per TS ho dovuto aggiungere un operatore unario sulet seconds = Math.floor((+new Date() - date) / 1000);
Ben Racicot,

Perché controlli anche interval === 0negli ultimi if?
smartmouse

1
@smartmouse in modo che pronunci "0 secondi" anziché "0 secondi"
rob

14

Potresti voler guardare humanized_time_span: https://github.com/layam/js_humanized_time_span

È agnostico e completamente personalizzabile.

Basta scaricare / includere lo script e quindi è possibile farlo:

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'

o anche questo:

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"

Leggi i documenti per maggiori informazioni.


4
Significa solo che non si basa su jQuery o addirittura su un DOM.
Will Tomlins, il

Mi dà NaN years agoperché ??

maledizione l'ho capito ... il tuo esempio del suo uso è sbagliato. in realtà delimiti i primi numeri con la barra anziché "-" .. in questo modohumanized_time_span("2011/05/11 12:00:00")

potrebbe dipendere dalla tua cultura locale e differire tra gli utenti :)
mikus,

13

Modificata la funzione sopra in

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";
}

Altrimenti mostrerebbe cose come "75 minuti" (tra 1 e 2 ore). Inoltre ora presuppone che la data di input sia un timestamp Unix.


Dividi la data per 1000 per favore.

Ho usato questo in cui i dati provenivano da un database con timestamp Unix in pochi secondi. Quando è in millisecondi devi dividere per 1000.
PanMan

11

Codice molto leggibile e compatibile con più browser:

Come indicato da @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'));


Si noti che questo fa alcune assunzioni errate, come ogni giorno che è 86.400 secondi (a meno che il fuso orario non sia impostato su UTC, questo non è sempre vero grazie a UTC)
ItalyPaleAle

10

Una versione più corta utilizzata da 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'intervallo più breve ha una durata di zero secondi: ciò comporta una divisione per errore zero.
apk

@apk ha ragione. <60 secondi stampaInfinity seconds ago
leonheess

8

da ora, unix timestamp param,

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

Una versione ES6 del codice fornita da @ 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`;
};

Modificato con i suggerimenti di @ ibe-vanmeenen. (Grazie !)


Dovresti anche includere "secondo: 1" in EPOCHS, altrimenti si romperà se è meno di 1 minuto fa :). Gli ultimi 3 var potrebbero anche essere un costante no?
Ibe Vanmeenen,

1
Inoltre, EPOCHS dovrebbe essere un array, poiché gli oggetti non garantiscono l'ordine delle proprietà. Ho memorizzato le mie modifiche in gist.github.com/IbeVanmeenen/4e3e58820c9168806e57530563612886 . Puoi copiarli per modificare questa risposta :)
Ibe Vanmeenen,

5

Versione semplice e leggibile:

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

Ne scrivo uno con js e python, usato in due progetti, molto carino e semplice: una semplice libreria (meno di 2kb) usata per formattare la data con*** time ago un'istruzione.

semplice, piccolo, facile da usare e ben testato.

  1. npm install timeago.js

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

  3. usa api format.

Campione:

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

Inoltre puoi eseguire il rendering in tempo reale.

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

A partire da 4.0 è invece possibile utilizzare un'importazione destrutturata:import { format, render, cancel, register } from 'timeago.js';
cmfolio

3

Sebbene la domanda sia stata posta molto tempo fa, scrivere questa risposta con la speranza che possa aiutare qualcuno.

Passa la data da cui vuoi iniziare a contare. Utilizzo moment().fromNow()di momentjs : (Vedi maggiori informazioni qui )

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

Se desideri modificare le informazioni fornite per le date da Ora scrivi il tuo tempo relativo personalizzato per il momento.

Ad esempio, nel mio caso, volevo stampare 'one month ago'invece di 'a month ago'( fornito da moment (d) .fromNow () ). In questo caso, puoi scrivere qualcosa di seguito.

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

NOTA : ho scritto il mio codice per il progetto in Agular 6


3

Puoi anche usare il plugin dayjs relativeTime per risolvere questo problema.

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

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

3

Questo dovrebbe gestire correttamente qualsiasi timestamp valido, inclusi Date.now (), singole unità e date future. Ho lasciato fuori mesi, ma quelli dovrebbero essere facili da aggiungere. Ho cercato di renderlo leggibile il più possibile.

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

Ho modificato la versione di Sky Sanders. Le operazioni Math.floor (...) vengono valutate nel blocco 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();
            }
        }

c'è un errore di battitura nell'ultimo caso return days + "1 day ago";, se dovrebbe esserereturn "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

La mia soluzione

(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

La mia pugnalata si basa su altre risposte.

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

Stavo cercando una risposta a questo e ho quasi implementato una di queste soluzioni, ma un collega mi ha ricordato di controllare react-intl biblioteca dal momento che la stavamo già utilizzando.

Quindi aggiungendo alle soluzioni ... nel caso in cui si stia utilizzando la react-intllibreria, hanno un <FormattedRelative>componente per questo.

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


0

Ecco cosa ho fatto (l'oggetto restituisce l'unità di tempo insieme al suo valore):

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.