Files
api/composables/time.ts
2023-08-07 17:51:36 -07:00

141 lines
3.6 KiB
TypeScript

import dayjs, { extend } from 'dayjs';
import localizedFormat from 'dayjs/plugin/localizedFormat';
/** @see https://day.js.org/docs/en/display/format#localized-formats */
extend(localizedFormat);
export interface TimeStringsObject {
years: number;
months: number;
days: number;
hours: number;
minutes: number;
seconds: number;
firstDateWasLater: boolean;
displaySeconds?: boolean;
}
const useTimeHelper = (t: any) => {
const buildStringFromValues = (payload: TimeStringsObject) => {
const {
years,
months,
days,
hours,
minutes,
seconds,
firstDateWasLater,
displaySeconds,
} = payload;
const result = [];
if (years) { result.push(t('year', years)); }
if (months) { result.push(t('month', months)); }
if (days) { result.push(t('day', days)); }
if (hours) { result.push(t('hour', hours)); }
if (minutes) { result.push(t('minute', minutes)); }
if (seconds && ((!years && !months && !days && !hours && !minutes) || displaySeconds)) { result.push(t('second', seconds)); }
if (firstDateWasLater) { result.push(t('ago')); }
return result.join(' ');
};
const formatDate = (date: number): string => dayjs(date).format('llll');
/**
* Original meat and potatos from:
* @version: 1.0.1
* @author: huangjinlin
* @repo: https://github.com/huangjinlin/dayjs-precise-range
*/
const buildValueObject = (
yDiff: number,
mDiff: number,
dDiff: number,
hourDiff: number,
minDiff: number,
secDiff: number,
firstDateWasLater: boolean
): TimeStringsObject => ({
years: yDiff,
months: mDiff,
days: dDiff,
hours: hourDiff,
minutes: minDiff,
seconds: secDiff,
firstDateWasLater,
});
const preciseDateDiff = (d1: dayjs.Dayjs, d2: dayjs.Dayjs): TimeStringsObject => {
let m1 = dayjs(d1);
let m2 = dayjs(d2);
let firstDateWasLater;
if (m1.isSame(m2)) {
return buildValueObject(0, 0, 0, 0, 0, 0, false);
}
if (m1.isAfter(m2)) {
const tmp = m1;
m1 = m2;
m2 = tmp;
firstDateWasLater = true;
} else {
firstDateWasLater = false;
}
let yDiff = m2.year() - m1.year();
let mDiff = m2.month() - m1.month();
let dDiff = m2.date() - m1.date();
let hourDiff = m2.hour() - m1.hour();
let minDiff = m2.minute() - m1.minute();
let secDiff = m2.second() - m1.second();
if (secDiff < 0) {
secDiff = 60 + secDiff;
minDiff -= 1;
}
if (minDiff < 0) {
minDiff = 60 + minDiff;
hourDiff -= 1;
}
if (hourDiff < 0) {
hourDiff = 24 + hourDiff;
dDiff -= 1;
}
if (dDiff < 0) {
const daysInLastFullMonth = dayjs(`${m2.year()}-${m2.month() + 1}`).subtract(1, 'M').daysInMonth();
if (daysInLastFullMonth < m1.date()) { // 31/01 -> 2/03
dDiff = daysInLastFullMonth + dDiff + (m1.date() - daysInLastFullMonth);
} else {
dDiff = daysInLastFullMonth + dDiff;
}
mDiff -= 1;
}
if (mDiff < 0) {
mDiff = 12 + mDiff;
yDiff -= 1;
}
return buildValueObject(yDiff, mDiff, dDiff, hourDiff, minDiff, secDiff, firstDateWasLater);
};
const readableDifference = (a = '', b = '') => {
try {
const x = a ? dayjs(parseInt(a, 10)) : dayjs();
const y = b ? dayjs(parseInt(b, 10)) : dayjs();
return preciseDateDiff(x, y);
} catch (error) {
throw new Error('Couldn\'t calculate date difference');
}
};
const dateDiff = (time: string, countUp: boolean) => countUp ? readableDifference(time, '') : readableDifference('', time);
return {
buildStringFromValues,
dateDiff,
formatDate,
};
};
export default useTimeHelper;