2011-05-24 18 views

Respuesta

62

Bueno, es bastante fácil si no está demasiado preocupado con la precisión. ¿Qué pasa con el método trivial?

function timeDifference(current, previous) { 

    var msPerMinute = 60 * 1000; 
    var msPerHour = msPerMinute * 60; 
    var msPerDay = msPerHour * 24; 
    var msPerMonth = msPerDay * 30; 
    var msPerYear = msPerDay * 365; 

    var elapsed = current - previous; 

    if (elapsed < msPerMinute) { 
     return Math.round(elapsed/1000) + ' seconds ago'; 
    } 

    else if (elapsed < msPerHour) { 
     return Math.round(elapsed/msPerMinute) + ' minutes ago'; 
    } 

    else if (elapsed < msPerDay) { 
     return Math.round(elapsed/msPerHour) + ' hours ago'; 
    } 

    else if (elapsed < msPerMonth) { 
     return 'approximately ' + Math.round(elapsed/msPerDay) + ' days ago'; 
    } 

    else if (elapsed < msPerYear) { 
     return 'approximately ' + Math.round(elapsed/msPerMonth) + ' months ago'; 
    } 

    else { 
     return 'approximately ' + Math.round(elapsed/msPerYear) + ' years ago'; 
    } 
} 

Ejemplo de trabajo here.

Es posible que desee ajustarlo para manejar mejor los valores singulares (por ejemplo, 1 day en lugar de 1 days) si eso le molesta.

+0

Brill! ¡Justo lo que estaba buscando! Conocía el principio básico, pero quería asegurarme de que definitivamente era la mejor manera de hacerlo :) – wilsonpage

5

Tada! Timeago: http://timeago.yarp.com/

Oh, colgar, sin complementos? ¿Por qué es eso entonces? Supongo que podrías abrir el archivo de complemento y cortar las agallas.

+0

Bueno, eso en realidad es un complemento. El OP pide una solución sin usar una. – pimvdb

+0

Solo quiero mantener el código lo más limpio posible y totalmente personalizable. No creo que sea una gran diversión. Poss 10-15 líneas, por lo tanto, no necesitan la otra funcionalidad incluida en un complemento. – wilsonpage

+1

De acuerdo, el código fuente es bastante corto y parece que podría extraerse según sus necesidades, siempre que conserve el encabezado de licencia de MIT. http://timeago.yarp.com/jquery.timeago.js –

13

Aquí es exacta mímica de hace tiempo de Twitter sin plugins:

function timeSince(timeStamp) { 
    var now = new Date(), 
     secondsPast = (now.getTime() - timeStamp.getTime())/1000; 
    if(secondsPast < 60){ 
     return parseInt(secondsPast) + 's'; 
    } 
    if(secondsPast < 3600){ 
     return parseInt(secondsPast/60) + 'm'; 
    } 
    if(secondsPast <= 86400){ 
     return parseInt(secondsPast/3600) + 'h'; 
    } 
    if(secondsPast > 86400){ 
     day = timeStamp.getDate(); 
     month = timeStamp.toDateString().match(/ [a-zA-Z]*/)[0].replace(" ",""); 
     year = timeStamp.getFullYear() == now.getFullYear() ? "" : " "+timeStamp.getFullYear(); 
     return day + " " + month + year; 
    } 
    } 

Gist https://gist.github.com/timuric/11386129

violín http://jsfiddle.net/qE8Lu/1/

espero que ayude.

+0

¡Usted, señor, sabe cosas! Muchas gracias. ¿Por qué usar una biblioteca de terceros, verdad? – zanona

1

Para cualquier persona interesada, terminé creando un ayudante de manubrio para hacer esto. Uso:

{{#beautify_date}} 
     {{timestamp_ms}} 
    {{/beautify_date}} 

Ayudante:

Handlebars.registerHelper('beautify_date', function(options) { 
     var timeAgo = new Date(parseInt(options.fn(this))); 

     if (Object.prototype.toString.call(timeAgo) === "[object Date]") { 
      if (isNaN(timeAgo.getTime())) { 
       return 'Not Valid'; 
      } else { 
       var seconds = Math.floor((new Date() - timeAgo)/1000), 
       intervals = [ 
        Math.floor(seconds/31536000), 
        Math.floor(seconds/2592000), 
        Math.floor(seconds/86400), 
        Math.floor(seconds/3600), 
        Math.floor(seconds/60) 
       ], 
       times = [ 
        'year', 
        'month', 
        'day', 
        'hour', 
        'minute' 
       ]; 

       var key; 
       for(key in intervals) { 
        if (intervals[key] > 1) 
         return intervals[key] + ' ' + times[key] + 's ago'; 
        else if (intervals[key] === 1) 
         return intervals[key] + ' ' + times[key] + ' ago'; 
       } 

       return Math.floor(seconds) + ' seconds ago'; 
      } 
     } else { 
      return 'Not Valid'; 
     } 
    }); 
2

Inspirated en Diego Castillo awnser's y en el timeago.js plugin, me escribió mi propio plugin de vainilla para esto.

var timeElement = document.querySelector('time'), 
    time = new Date(timeElement.getAttribute('datetime')); 

timeElement.innerText = TimeAgo.inWords(time.getTime()); 

var TimeAgo = (function() { 
 
    var self = {}; 
 
    
 
    // Public Methods 
 
    self.locales = { 
 
    prefix: '', 
 
    sufix: 'ago', 
 
    
 
    seconds: 'less than a minute', 
 
    minute: 'about a minute', 
 
    minutes: '%d minutes', 
 
    hour: 'about an hour', 
 
    hours: 'about %d hours', 
 
    day:  'a day', 
 
    days: '%d days', 
 
    month: 'about a month', 
 
    months: '%d months', 
 
    year: 'about a year', 
 
    years: '%d years' 
 
    }; 
 
    
 
    self.inWords = function(timeAgo) { 
 
    var seconds = Math.floor((new Date() - parseInt(timeAgo))/1000), 
 
     separator = this.locales.separator || ' ', 
 
     words = this.locales.prefix + separator, 
 
     interval = 0, 
 
     intervals = { 
 
      year: seconds/31536000, 
 
      month: seconds/2592000, 
 
      day: seconds/86400, 
 
      hour: seconds/3600, 
 
      minute: seconds/60 
 
     }; 
 
    
 
    var distance = this.locales.seconds; 
 
    
 
    for (var key in intervals) { 
 
     interval = Math.floor(intervals[key]); 
 
     
 
     if (interval > 1) { 
 
     distance = this.locales[key + 's']; 
 
     break; 
 
     } else if (interval === 1) { 
 
     distance = this.locales[key]; 
 
     break; 
 
     } 
 
    } 
 
    
 
    distance = distance.replace(/%d/i, interval); 
 
    words += distance + separator + this.locales.sufix; 
 

 
    return words.trim(); 
 
    }; 
 
    
 
    return self; 
 
}()); 
 

 

 
// USAGE 
 
var timeElement = document.querySelector('time'), 
 
    time = new Date(timeElement.getAttribute('datetime')); 
 

 
timeElement.innerText = TimeAgo.inWords(time.getTime());
<time datetime="2016-06-13"></time>

3

plugins de fecha y hora existe porque es muy difícil hacerlo bien. Esta video explaining date-time inconsistencies arrojará algo de luz sobre el tema.

Todas las soluciones anteriores sin complementos son incorrectas.

Para trabajar con fechas y horas usando un complemento es preferible. De los cientos de complementos que se ocupan de él, utilizamos Moment.js y está haciendo el trabajo.

Desde el twitter API dcumentation podemos ver su formato de hora:

"created_at":"Wed Aug 27 13:08:45 +0000 2008" 

Nos puede analizar con él con Moment.js

const postDatetime = moment(
    "Wed Aug 27 13:08:45 +0000 2008", 
    "dddd, MMMM Do, h:mm:ss a, YYYY" 
); 
const now = moment(); 
const timeAgo = now.diff(postDatetime, 'seconds'); 

Para especificar la unidad de tiempo preferido para la diff, podemos utilizar el isSame método. por ejemplo:

if (now.isSame(postDatetime, 'day')) { 
    const timeUnit = 'days'; 
} 

En general, la construcción de algo como:

`Posted ${timeAgo} ${timeUnit} ago`; 

Consulte la documentación de su plug-in para el manejo de tiempo relativo (es decir: "¿Cuánto tiempo hace") cálculos.

1

También hay sugar.js y relative función para este propósito.

relative - Da salida a una cadena en unidades relativa a la fecha actual ("ago" o "from now").

0

Puede usar machinepack-datetime para este fin. Es fácil y claro con su API definida.

tutorialSchema.virtual('createdOn').get(function() { 
    const DateTime = require('machinepack-datetime'); 
    let timeAgoString = ""; 
    try { 
     timeAgoString = DateTime.timeFrom({ 
      toWhen: DateTime.parse({ 
       datetime: this.createdAt 
      }).execSync(), 
      fromWhen: new Date().getTime() 
     }).execSync(); 
    } catch(err) { 
     console.log('error getting createdon', err); 
    } 
    return timeAgoString; // a second ago 
}); 
0

Si necesita varios idiomas y no desea agregar una gran biblioteca como momento. intl-relativeformat de yahoo es una buena solución.

var rf = new IntlRelativeFormat('en-US'); 

var posts = [ 
    { 
     id : 1, 
     title: 'Some Blog Post', 
     date : new Date(1426271670524) 
    }, 
    { 
     id : 2, 
     title: 'Another Blog Post', 
     date : new Date(1426278870524) 
    } 
]; 

posts.forEach(function (post) { 
    console.log(rf.format(post.date)); 
}); 
// => "3 hours ago" 
// => "1 hour ago" 
Cuestiones relacionadas