@videsk/humanize-date
Version:
Humanize dates making readable in locale and ultra lightweight
176 lines (157 loc) • 6.78 kB
JavaScript
class HumanizeDate {
constructor() {
this.from = new Date();
this.to = new Date();
this.units = {
seconds: this.seconds,
minutes: this.minutes,
hours: this.hours,
days: this.days,
weeks: this.weeks,
months: this.months,
years: this.years,
quarters: this.quarters,
auto: this.auto,
}
}
/**
* Convert date to human readable
* @param date {String|Number|Date} - Date want format
* @param options {Object} - Check options here: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString
*/
toLocale(date = new Date(), options = { year: 'numeric', month: 'long', day: 'numeric' }) {
return new Date(date).toLocaleDateString(navigator.language, options);
}
/**
* Set dates
* @param dateA {String|Number|Date|Array|Object}
* @param dateB= {String|Number|Date}
* @returns {HumanizeDate}
*/
dates(dateA= new Date(), dateB = new Date()) {
const { from, to } = this.constructor.getDates(dateA, dateB);
this.from = new Date(from);
this.to = new Date(to);
return this;
}
/**
* Convert difference of two dates in relative time human readable
* @param unit {String} - Unit as seconds, minutes, hours, weeks, months, years
* @param options {Object} - Check options here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat
* @returns {string}
*/
within(unit = 'seconds', options = { numeric: 'auto' }) {
if (!(unit in this.units)) throw new Error(`The available units are ${Object.keys(this.units)}`);
return new Intl.RelativeTimeFormat(navigator.language, options).format(Math.floor(this.units[unit](this.from, this.to)), (unit !== 'auto') ? unit : this.autoToUnitText(this.from, this.to));
}
/**
* Convert difference of two dates in relative time human readable
* @param unit {String} - Unit as seconds, minutes, hours, weeks, months, years
* @param options {Object} - Check options here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat
* @returns {string}
*/
ago(unit = 'seconds', options = { numeric: 'auto' }) {
if (!(unit in this.units)) throw new Error(`The available units are ${Object.keys(this.units)}`);
return new Intl.RelativeTimeFormat(navigator.language, options).format(Math.floor(this.units[unit](this.from, this.to) * -1), (unit !== 'auto') ? unit : this.autoToUnitText(this.from, this.to));
}
/**
* Get difference between dates in seconds
* @param from= {String|Number|Date} - The older date
* @param to= {String|Number|Date} - The newer date
* @returns {number}
*/
seconds(from, to) {
return Math.abs(new Date(to || this.to) - new Date(from || this.from)) / 1000;
}
/**
* Get difference between dates in minutes
* @param from= {String|Number|Date} - The older date
* @param to= {String|Number|Date} - The newer date
* @returns {number}
*/
minutes(from, to) {
return Math.abs(new Date(to || this.to) - new Date(from || this.from)) / (1000 * 60);
}
/**
* Get difference between dates in hours
* @param from= {String|Number|Date} - The older date
* @param to= {String|Number|Date} - The newer date
* @returns {number}
*/
hours(from, to) {
return Math.abs(new Date(to || this.to) - new Date(from || this.from)) / (1000 * 60 * 60);
}
/**
* Get difference between dates in days
* @param from= {String|Number|Date} - The older date
* @param to= {String|Number|Date} - The newer date
* @returns {number}
*/
days(from, to) {
return Math.abs(new Date(to || this.to) - new Date(from || this.from)) / (1000 * 60 * 60 * 24);
}
/**
* Get difference between dates in weeks
* @param from= {String|Number|Date} - The older date
* @param to= {String|Number|Date} - The newer date
* @returns {number}
*/
weeks(from, to) {
return Math.abs(new Date(to || this.to) - new Date(from || this.from)) / (1000 * 60 * 60 * 24 * 7 * 4);
}
/**
* Get difference between dates in months
* @param from= {String|Number|Date} - The older date
* @param to= {String|Number|Date} - The newer date
* @returns {number}
*/
months(from, to) {
return Math.abs((this.years(from, to) * 12) + (new Date(to || this.to).getMonth() - new Date(from || this.from).getMonth()));
}
/**
* Get difference between dates in years
* @param from= {String|Number|Date} - The older date
* @param to= {String|Number|Date} - The newer date
* @returns {number}
*/
years(from, to) {
return Math.abs(new Date(to || this.to).getFullYear() - new Date(from || this.from).getFullYear());
}
/**
* Get difference between dates in quarters
* @param from= {String|Number|Date} - The older date
* @param to= {String|Number|Date} - The newer date
* @returns {number}
*/
quarters(from, to) {
return Math.abs(this.months(from, to) / 4);
}
auto(from, to) {
if (this.seconds(from, to) <= 60) return this.seconds(from, to);
else if (this.minutes(from, to) <= 60) return this.minutes(from, to);
else if (this.hours(from, to) <= 24) return this.hours(from, to);
else if (this.days(from, to) <= 31) return this.days(from, to);
else if (this.months(from, to) <= 12) return this.months(from, to);
else return this.years(from, to);
}
autoToUnitText(from, to) {
if (this.seconds(from, to) <= 60) return 'seconds';
else if (this.minutes(from, to) <= 60) return 'minutes';
else if (this.hours(from, to) <= 24) return 'hours';
else if (this.days(from, to) <= 31) return 'days';
else if (this.months(from, to) <= 12) return 'months';
else return 'years';
}
/**
* Get dates based on parameters
* @param from {String|Number|Date|Array|Object}
* @param to {String|Number|Date}
* @returns {{from: *, to: *}|{from: (string|number), to}}
*/
static getDates(from, to) {
if (!(Array.isArray(from) || typeof from === 'object') || (typeof from === 'object' && 'getTime' in from)) return {from, to};
else if (Array.isArray(from)) return {from: from[0], to: from[1]};
else if (typeof from === 'object') return {from: from[Object.keys(from)[0]], to: from[Object.keys(from)[1]]};
}
}
module.exports = HumanizeDate;