Skip to content

Instantly share code, notes, and snippets.

@artemgurzhii
Last active May 11, 2017 07:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save artemgurzhii/bc54d942c33f4dea3dcb160957482f5a to your computer and use it in GitHub Desktop.
Save artemgurzhii/bc54d942c33f4dea3dcb160957482f5a to your computer and use it in GitHub Desktop.
Time ago in words should be calculated on the client side. http://rails-bestpractices.com/posts/2012/02/10/not-use-time_ago_in_words/
import DateHelper from './modules/dateHelper';
const dataInit = new DateHelper();
const _timeAgoElems = document.querySelectorAll('.time-ago-in-words');
[..._timeAgoElems].forEach(elem => {
const time = elem.querySelector('time');
time.textContent = dataInit.timeAgoInWords(time.dataset.time);
});
// helper to work with date object
export default class DateHelper {
constructor() {
this.timeAgo = {
LESS_THAN_MINUTE: 0,
MINUTE: 1,
THREE_QUARTERS: 45,
HOUR: 60,
HOUR_AND_A_HALF: 90,
DAY: 1440,
TWO_DAYS: 2880,
MONTH: 43200,
TWO_MONTHS: 86400,
YEAR: 525600,
TWO_YEARS: 1051200,
};
}
// get formated time ago in words
timeAgoInWords(from) {
const date = new Date();
date.setTime(Date.parse(from));
return this.timeInWords(new Date(), date);
}
// return tiem in words as a string
timeInWords(to, from) {
const seconds = (to - from) / 1000;
const minutes = Math.abs(Math.floor(seconds / this.timeAgo.HOUR));
const tense = seconds < 0 ? ' from now' : ' ago';
if (minutes === this.timeAgo.LESS_THAN_MINUTE) {
return `less than a minute${tense}`;
}
if (minutes === this.timeAgo.MINUTE) {
return `a minute${tense}`;
}
if (minutes < this.timeAgo.THREE_QUARTERS) {
return `${minutes} minutes${tense}`;
}
if (minutes < this.timeAgo.HOUR_AND_A_HALF) {
return `about an hour${tense}`;
}
if (minutes < this.timeAgo.DAY) {
return `about ${Math.floor(minutes / this.timeAgo.HOUR)} hours${tense}`;
}
if (minutes < this.timeAgo.TWO_DAYS) {
return `a day${tense}`;
}
if (minutes < this.timeAgo.MONTH) {
return `${Math.floor(minutes / this.timeAgo.DAY)} days${tense}`;
}
if (minutes < this.timeAgo.TWO_MONTHS) {
return `about a month${tense}`;
}
if (minutes < this.timeAgo.YEAR) {
return `${Math.floor(minutes / this.timeAgo.MONTH)} months${tense}`;
}
if (minutes < this.timeAgo.TWO_YEARS) {
return `about a year${tense}`;
}
return `over ${Math.floor(minutes / this.timeAgo.YEAR)} years`;
}
}
<div id="posts">
<% @posts.each do |post| %>
<div class="post-<%= post.id %>">
<p class="date time-ago-in-words">
Published <time data-time="<%= post.created_at.to_s %>"></time> by <%= post.user_email %>
</p>
</div>
<% end %>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment