init commit,
This commit is contained in:
290
03_source/frontend/src/utils/format-time.ts
Normal file
290
03_source/frontend/src/utils/format-time.ts
Normal file
@@ -0,0 +1,290 @@
|
||||
import type { Dayjs, OpUnitType } from 'dayjs';
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @Docs
|
||||
* https://day.js.org/docs/en/display/format
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default timezones
|
||||
* https://day.js.org/docs/en/timezone/set-default-timezone#docsNav
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* UTC
|
||||
* https://day.js.org/docs/en/plugin/utc
|
||||
* @install
|
||||
* import utc from 'dayjs/plugin/utc';
|
||||
* dayjs.extend(utc);
|
||||
* @usage
|
||||
* dayjs().utc().format()
|
||||
*
|
||||
*/
|
||||
|
||||
dayjs.extend(duration);
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export type DatePickerFormat = Dayjs | Date | string | number | null | undefined;
|
||||
|
||||
export const formatPatterns = {
|
||||
dateTime: 'DD MMM YYYY h:mm a', // 17 Apr 2022 12:00 am
|
||||
date: 'DD MMM YYYY', // 17 Apr 2022
|
||||
time: 'h:mm a', // 12:00 am
|
||||
split: {
|
||||
dateTime: 'DD/MM/YYYY h:mm a', // 17/04/2022 12:00 am
|
||||
date: 'DD/MM/YYYY', // 17/04/2022
|
||||
},
|
||||
paramCase: {
|
||||
dateTime: 'DD-MM-YYYY h:mm a', // 17-04-2022 12:00 am
|
||||
date: 'DD-MM-YYYY', // 17-04-2022
|
||||
},
|
||||
};
|
||||
|
||||
const isValidDate = (date: DatePickerFormat) =>
|
||||
date !== null && date !== undefined && dayjs(date).isValid();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function today(template?: string): string {
|
||||
return dayjs(new Date()).startOf('day').format(template);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @output 17 Apr 2022 12:00 am
|
||||
*/
|
||||
export function fDateTime(date: DatePickerFormat, template?: string): string {
|
||||
if (!isValidDate(date)) {
|
||||
return 'Invalid date';
|
||||
}
|
||||
|
||||
return dayjs(date).format(template ?? formatPatterns.dateTime);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @output 17 Apr 2022
|
||||
*/
|
||||
export function fDate(date: DatePickerFormat, template?: string): string {
|
||||
if (!isValidDate(date)) {
|
||||
return 'Invalid date';
|
||||
}
|
||||
|
||||
return dayjs(date).format(template ?? formatPatterns.date);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @output 12:00 am
|
||||
*/
|
||||
export function fTime(date: DatePickerFormat, template?: string): string {
|
||||
if (!isValidDate(date)) {
|
||||
return 'Invalid date';
|
||||
}
|
||||
|
||||
return dayjs(date).format(template ?? formatPatterns.time);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @output 1713250100
|
||||
*/
|
||||
export function fTimestamp(date: DatePickerFormat): number | 'Invalid date' {
|
||||
if (!isValidDate(date)) {
|
||||
return 'Invalid date';
|
||||
}
|
||||
|
||||
return dayjs(date).valueOf();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @output a few seconds, 2 years
|
||||
*/
|
||||
export function fToNow(date: DatePickerFormat): string {
|
||||
if (!isValidDate(date)) {
|
||||
return 'Invalid date';
|
||||
}
|
||||
|
||||
return dayjs(date).toNow(true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @output boolean
|
||||
*/
|
||||
export function fIsBetween(
|
||||
inputDate: DatePickerFormat,
|
||||
startDate: DatePickerFormat,
|
||||
endDate: DatePickerFormat
|
||||
): boolean {
|
||||
if (!isValidDate(inputDate) || !isValidDate(startDate) || !isValidDate(endDate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const formattedInputDate = fTimestamp(inputDate);
|
||||
const formattedStartDate = fTimestamp(startDate);
|
||||
const formattedEndDate = fTimestamp(endDate);
|
||||
|
||||
if (
|
||||
formattedInputDate === 'Invalid date' ||
|
||||
formattedStartDate === 'Invalid date' ||
|
||||
formattedEndDate === 'Invalid date'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return formattedInputDate >= formattedStartDate && formattedInputDate <= formattedEndDate;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @output boolean
|
||||
*/
|
||||
export function fIsAfter(startDate: DatePickerFormat, endDate: DatePickerFormat): boolean {
|
||||
if (!isValidDate(startDate) || !isValidDate(endDate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return dayjs(startDate).isAfter(endDate);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @output boolean
|
||||
*/
|
||||
export function fIsSame(
|
||||
startDate: DatePickerFormat,
|
||||
endDate: DatePickerFormat,
|
||||
unitToCompare?: OpUnitType
|
||||
): boolean {
|
||||
if (!isValidDate(startDate) || !isValidDate(endDate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return dayjs(startDate).isSame(endDate, unitToCompare ?? 'year');
|
||||
}
|
||||
|
||||
/**
|
||||
* @output
|
||||
* Same day: 26 Apr 2024
|
||||
* Same month: 25 - 26 Apr 2024
|
||||
* Same month: 25 - 26 Apr 2024
|
||||
* Same year: 25 Apr - 26 May 2024
|
||||
*/
|
||||
export function fDateRangeShortLabel(
|
||||
startDate: DatePickerFormat,
|
||||
endDate: DatePickerFormat,
|
||||
initial?: boolean
|
||||
): string {
|
||||
if (!isValidDate(startDate) || !isValidDate(endDate) || fIsAfter(startDate, endDate)) {
|
||||
return 'Invalid date';
|
||||
}
|
||||
|
||||
let label = `${fDate(startDate)} - ${fDate(endDate)}`;
|
||||
|
||||
if (initial) {
|
||||
return label;
|
||||
}
|
||||
|
||||
const isSameYear = fIsSame(startDate, endDate, 'year');
|
||||
const isSameMonth = fIsSame(startDate, endDate, 'month');
|
||||
const isSameDay = fIsSame(startDate, endDate, 'day');
|
||||
|
||||
if (isSameYear && !isSameMonth) {
|
||||
label = `${fDate(startDate, 'DD MMM')} - ${fDate(endDate)}`;
|
||||
} else if (isSameYear && isSameMonth && !isSameDay) {
|
||||
label = `${fDate(startDate, 'DD')} - ${fDate(endDate)}`;
|
||||
} else if (isSameYear && isSameMonth && isSameDay) {
|
||||
label = `${fDate(endDate)}`;
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @output 2024-05-28T05:55:31+00:00
|
||||
*/
|
||||
export type DurationProps = {
|
||||
years?: number;
|
||||
months?: number;
|
||||
days?: number;
|
||||
hours?: number;
|
||||
minutes?: number;
|
||||
seconds?: number;
|
||||
milliseconds?: number;
|
||||
};
|
||||
|
||||
export function fAdd({
|
||||
years = 0,
|
||||
months = 0,
|
||||
days = 0,
|
||||
hours = 0,
|
||||
minutes = 0,
|
||||
seconds = 0,
|
||||
milliseconds = 0,
|
||||
}: DurationProps) {
|
||||
const result = dayjs()
|
||||
.add(
|
||||
dayjs.duration({
|
||||
years,
|
||||
months,
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
milliseconds,
|
||||
})
|
||||
)
|
||||
.format();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @output 2024-05-28T05:55:31+00:00
|
||||
*/
|
||||
export function fSub({
|
||||
years = 0,
|
||||
months = 0,
|
||||
days = 0,
|
||||
hours = 0,
|
||||
minutes = 0,
|
||||
seconds = 0,
|
||||
milliseconds = 0,
|
||||
}: DurationProps) {
|
||||
const result = dayjs()
|
||||
.subtract(
|
||||
dayjs.duration({
|
||||
years,
|
||||
months,
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
milliseconds,
|
||||
})
|
||||
)
|
||||
.format();
|
||||
|
||||
return result;
|
||||
}
|
Reference in New Issue
Block a user