Cómo formatear el tiempo desde xxx, por ejemplo, "hace 4 minutos" similar a los sitios de Stack Exchange


210

La pregunta es cómo formatear un JavaScript Datecomo una cadena que indica que el tiempo transcurrido es similar a la forma en que ves las horas que se muestran en Stack Overflow.

p.ej

  • Hace 1 minuto
  • 1 hora antes
  • Hace 1 día
  • Hace 1 mes
  • hace 1 año



Respuestas:


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: sí, el único punto de salida tiene sus virtudes cuando no se interpone en el camino. aquellos que lo toman demasiado en serio en estos días están malentendiendo el origen de la máxima.
Sky Sanders

36
Buena función, pero algunas observaciones. Cambió la primera línea a: var segundos = Math.floor (((new Date (). GetTime () / 1000) - date)) para trabajar con marcas de tiempo Unix. Y necesitaba cambiar el intval> 1 a intval> = 1, de lo contrario, mostraría cosas como 75 minutos (entre 1 y 2 horas).
PanMan

3
@PanMan si solo cambias> a> = entonces terminarás con tiempos como "1 minutos". Publiqué una versión modificada de esta respuesta que agrega condicionalmente la "s": stackoverflow.com/a/23259289/373655
robe el

Nunca use la concatenación de cadenas, pero String.format si desea una solución que pueda internacionalizarse
rds

¿Qué pasa si quiero colocarlo en la clase div? ¿Que puedo hacer? Lo siento, no soy un profesional en JavaScript. Intenté este document.getElementsByTagName ('. Sampleclass') [0] .innerHTML = timeSince (date); y este document.getElementById ('idname') [0] .innerHTML = timeSince (fecha); Pero no está funcionando. ¿Alguna ayuda? Gracias.
x'tian

119

Puede ser una exageración en este caso, pero si la oportunidad muestra moment.js es simplemente increíble.

Moment.js es una biblioteca de fecha y hora de JavaScript, para usarla en ese escenario, haría:

moment(yourdate).fromNow()

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

Anexo 2018 : ¡ Luxon es una nueva biblioteca moderna y podría valer la pena!


Hola, estoy usando tu respuesta para que el tiempo sea diferente. ¿Qué puedo hacer si solo necesito las primeras letras del año como año, y, mes y día como d?
Nodirabegimxonoyim

57

No lo he comprobado (aunque no sería difícil), pero creo que los sitios de Stack Exchange usan el jquery.timeagocomplemento para crear estas cadenas de tiempo .


Es bastante fácil usar el complemento, y está limpio y se actualiza automáticamente.

Aquí hay una muestra rápida (de la página de inicio del complemento):

Primero, cargue jQuery y el complemento:

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

Ahora, adjúntelo a sus marcas de tiempo en DOM listo:

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

Esto convertirá todos los abbrelementos con una clase timeagoy una marca de tiempo ISO 8601 en el título: <abbr class="timeago" title="2008-07-17T09:24:17Z">July 17, 2008</abbr>en algo como esto: <abbr class="timeago" title="July 17, 2008">about a year ago</abbr>que produce: hace aproximadamente un año. A medida que pasa el tiempo, las marcas de tiempo se actualizarán automáticamente.


11
No todos usan JQuery.

2
No tiene sentido tener esto como un complemento jquery.
AlexG

57

Esto le mostrará formatos de tiempo pasados ​​y anteriores como 'Hace 2 días' 'dentro de 10 minutos' y puede pasarlo como un objeto Fecha, una marca de tiempo numérica o una cadena de fecha

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


Reemplace la última línea return time;con format = time_formats[time_formats.length - 1]; return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token;para devolver siglos durante largos períodos de tiempo en lugar de los milisegundos.
Aquila Sands

¡Muy agradable! Aunque noté en iOS, cuando se usa con angular como filtro, el navegador devuelve NaN aquí. Esto lo arregla: time = + new Date (time.replace (/ - / g, '/'));
Tiago

Genial, pero la asignación en ese ciclo while es fea y confusa. Cambiar a un ciclo forEach sería mejor
Martin Dawson

25

Aquí hay una pequeña modificación en la solución de Sky Sander que permite ingresar la fecha como una cadena y es capaz de mostrar tramos como "1 minuto" en lugar de "73 segundos"

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
Esto no funciona durante segundos ya que el intervalo se deja como 0 desde interval = Math.floor(seconds / 60);. Agregué interval = seconds;a la final elsey funciona bien.
howard10

2
Si el intervalo es 0, también debe agregar la "s".
JW.

Esto es asombroso Para TS tuve que agregar un operador unario enlet seconds = Math.floor((+new Date() - date) / 1000);
Ben Racicot

¿Por qué compruebas incluso interval === 0en el último if?
smartmouse

1
@smartmouse para que diga "0 segundos" en lugar de "0 segundos"
robe el

14

Es posible que desee ver humanized_time_span: https://github.com/layam/js_humanized_time_span

Es un marco agnóstico y totalmente personalizable.

Simplemente descargue / incluya el script y luego puede hacer esto:

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 incluso esto:

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"

Lea los documentos para más información.


44
Solo significa que no depende de jQuery o incluso de tener un DOM.
Will Tomlins

Me da NaN years agopor qué?

maldita sea, lo tengo ... tu ejemplo de su uso está mal. en realidad delimita los primeros números con una barra inclinada en lugar de "-" .. asíhumanized_time_span("2011/05/11 12:00:00")

puede depender de su cultura local y diferir entre los usuarios :)
mikus

13

Cambió la función anterior a

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

De lo contrario, mostraría cosas como "75 minutos" (entre 1 y 2 horas). También ahora supone que la fecha de entrada es una marca de tiempo de Unix.


Divide la fecha entre 1000 por favor.

Usé esto donde los datos provenían de una base de datos con marcas de tiempo Unix en segundos. Cuando está en milisegundos, debe dividir por 1000.
PanMan

11

Código mucho legible y compatible con el navegador cruzado:

Según lo dado por @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'));


Tenga en cuenta que esto hace algunas suposiciones erróneas, como que cada día sea 86,400 segundos (a menos que la zona horaria esté configurada en UTC, esto no siempre es cierto gracias a UTC)
ItalyPaleAle

10

Una versión más corta utilizada por 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
El intervalo más corto tiene una duración de cero segundos; esto da como resultado una división por cero error.
apk

@apk tiene razón. <60 segundos se imprimeInfinity seconds ago
leonheess

8

a partir de ahora, 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 versión ES6 del código proporcionado por @ 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`;
};

Editado con sugerencias de @ ibe-vanmeenen. (Gracias !)


También debe incluir "second: 1" en EPOCHS, de lo contrario se romperá si hace menos de 1 minuto :). Los últimos 3 vars también podrían ser un no constante?
Ibe Vanmeenen

1
Además, EPOCHS debe ser una matriz, ya que los objetos no garantizan el orden de las propiedades. He almacenado mis cambios en gist.github.com/IbeVanmeenen/4e3e58820c9168806e57530563612886 . Puedes copiarlos para editar esta respuesta :)
Ibe Vanmeenen

5

Versión simple y legible:

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

Escribo uno con js y python, usado en dos proyectos, muy agradable y simple: una biblioteca simple (menos de 2kb) utilizada para formatear la fecha con*** time ago declaración.

simple, pequeño, fácil de usar y bien probado.

  1. npm install timeago.js

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

  3. usar api format.

Muestra:

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

También puedes renderizar en tiempo real.

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

A partir de 4.0 puede usar una importación desestructurada en su lugar:import { format, render, cancel, register } from 'timeago.js';
cmfolio

3

Aunque la pregunta se hizo hace bastante tiempo, escribir esta respuesta con la esperanza de que ayude a alguien.

Pase la fecha desde la que desea comenzar a contar. Uso moment().fromNow()de momentjs : (Ver más información aquí )

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

Si desea cambiar la información proporcionada para las fechas de Ahora, escriba su hora relativa personalizada por el momento.

Por ejemplo, en mi propio caso quería imprimir en 'one month ago'lugar de 'a month ago'( provisto por moment (d) .fromNow () ). En este caso, puede escribir algo a continuación.

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 : Escribí mi código para el proyecto en Agular 6


3

También puede usar el complemento dayjs relativeTime para resolver esto.

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

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

3

Esto debería manejar adecuadamente cualquier marca de tiempo válida, incluyendo Date.now (), unidades singulares y fechas futuras. Dejé fuera meses, pero deberían ser fáciles de agregar. Traté de mantenerlo lo más legible posible.

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

He modificado la versión de Sky Sanders. Las operaciones Math.floor (...) se evalúan en el bloque 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();
            }
        }

hay un error tipográfico en el último si return days + "1 day ago";debería serreturn "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

Mi solución..

(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

Mi puñalada a esto se basa en otras respuestas.

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

Estaba buscando una respuesta a esto y casi implementé una de estas soluciones, pero un colega me recordó que revisara la react-intlbiblioteca ya que ya la estábamos usando.

Entonces, agregando a las soluciones ... en el caso de que esté utilizando la react-intlbiblioteca, tienen un <FormattedRelative>componente para esto.

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


0

Esto es lo que hice (el objeto devuelve la unidad de tiempo junto con su valor):

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.