I suggest this lovely library: countdown.js (Docs)
This is roughly how I use it in my Node bot:
const countdown = require('countdown');
// Bitwise OR these constants together. Comes out to the number 158.
// (You could just put 158 if you want my config)
const agoUnits = [ 'SECONDS', 'MINUTES', 'HOURS', 'DAYS', 'YEARS' ]
.reduce((p, n) => p |= countdown[n], 0);
// Applicable labels
const countdownLabels = '|s|m|h|d|||y|||';
// Apply the labels to singular and plural, space delimiter, and a default of "0s" for empty.
countdown.setLabels(countdownLabels, countdownLabels, ' ', ' ', '0s');
function ago(start, end = Date.now(), addSuffix = true) {
// Parse start, get the value.
start = new Date(start).getTime();
// Parse end, default to now
end = end === null ? Date.now() : new Date(end).getTime();
// If a date is not valid, it was NaN
if(start !== start || end !== end) { // NaN check
return null;
}
// Get our Timespan object
let c = countdown(start, end, agoUnits);
// Convert to a string
let cStr = c.toString();
// Add a nice suffix
if(addSuffix) {
cStr += ' ' + (c.value < 0 ? 'ago' : 'from now');
}
return cStr;
}
module.exports = { ago };
Example
const { ago } = require('./lib/utils');
let time = ago(stream.created_at);
console.log('Stream started', time);
// Stream started 4h 3m 28s ago
let time = ago(stream.created_at, null, false);
console.log('Stream started', time);
// Stream started 4h 3m 28s
// Without disabling the suffix in this order, it would add "from now"
let time = ago(stream.created_at, stream.channel.created_at, false);
console.log('Stream started', time, 'after the account was created');
// Stream started 6y 241d 18h 2s after the account was created