Timestamp Javascript al tempo relativo (ad esempio 2 secondi fa, una settimana fa ecc.), I metodi migliori?

Sto cercando un bel frammento JS per convertire un timestamp (ad es. Dall’API di Twitter) in un tempo relativo relativamente semplice da usare (ad es. 2 secondi fa, una settimana fa ecc.).

Qualcuno ha cura di condividere alcuni dei loro metodi preferiti (preferibilmente non usando i plugin)?

Beh, è ​​piuttosto facile se non sei eccessivamente preoccupato dell’accuratezza. Cosa c’è di sbagliato nel metodo banale?

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

Esempio di lavoro qui .

Potresti volerlo modificare per gestire meglio i valori singolari (ad esempio 1 day invece di 1 days ) se questo ti infastidisce.

Ecco la mimica esatta di Twitter tempo fa senza plugin:

  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

Fiddle http://jsfiddle.net/qE8Lu/1/

Spero che sia d’aiuto.

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

Oh aspetta – senza plugin? Perché è così? Immagino che potresti aprire il file del plugin e distruggerlo.

Ispirato a Diego Castillo awnser e nel plugin timeago.js , ho scritto il mio plugin per la vaniglia per questo.

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

I plugin datetime esistono perché è molto difficile farlo bene. Questo video che spiega le incongruenze date-time farà luce sul problema.

Tutte le soluzioni precedenti senza plug-in non sono corrette.

È preferibile lavorare con date e orari utilizzando un plug-in . Tra le centinaia di plugin che ne fanno uso, usiamo Moment.js e sta facendo il lavoro.

Dalla documentazione API di Twitter possiamo vedere il loro formato di timestamp:

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

Possiamo analizzarlo 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'); 

Per specificare l’unità di tempo preferita per il diff , possiamo usare il metodo isSame . per esempio:

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

Nel complesso, costruendo qualcosa come:

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

Fare riferimento alla documentazione del proprio plugin per la gestione dei tempi relativi (es .: “Quanto tempo fa?”).

Per chiunque fosse interessato, ho finito per creare un aiutante di Handlebars per farlo. Uso:

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

helper:

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

C’è anche sugar.js e la relativa funzione per questo scopo.

relativo – Emette una stringa in unità relativa alla data corrente (“fa” o “da ora”).

È ansible utilizzare machinepack-datetime per questo scopo. È facile e chiaro con la sua API definita.

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

Se hai bisogno di multilingue e non vuoi aggiungere una grande libreria come il momento. intl-relativeformat da yahoo è una bella soluzione.

 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"