jws-frontend/src/utils/datetime.ts
2025-01-09 17:34:23 +07:00

175 lines
4.2 KiB
TypeScript

import moment from 'moment';
import 'moment/dist/locale/th';
import { i18n } from 'src/boot/i18n';
import { Lang } from './ui';
moment.locale('en');
export function setLocale(locale: string) {
moment.locale(locale);
}
export function dateFormatJS(opts: {
date: string | Date | null;
locale?: string;
dayStyle?: 'numeric' | '2-digit';
monthStyle?: 'numeric' | '2-digit' | 'long' | 'short';
timeStyle?: 'full' | 'long' | 'medium' | 'short';
timeOnly?: boolean;
noDay?: boolean;
noMonth?: boolean;
noYear?: boolean;
withTime?: boolean;
}): string {
const dt = opts.date ? new Date(opts.date) : new Date();
const { locale } = i18n.global;
if (!opts.locale) {
opts.locale = locale.value === Lang.Thai ? 'th-TH' : 'en-US';
}
if (opts.timeOnly) {
opts.noDay = true;
opts.noMonth = true;
opts.noYear = true;
opts.timeStyle = opts.timeStyle || 'short';
}
let timeText = opts.withTime
? ' ' +
dateFormatJS({
date: opts.date,
timeOnly: true,
timeStyle: opts.timeStyle,
})
: '';
if (timeText) opts.timeStyle = undefined;
let formatted = new Intl.DateTimeFormat(opts.locale, {
day: opts.noDay ? undefined : opts.dayStyle || 'numeric',
month: opts.noMonth ? undefined : opts.monthStyle || 'short',
timeStyle: opts.timeStyle,
year: opts.noYear ? undefined : 'numeric',
}).format(dt);
switch (opts.locale) {
case Lang.Thai:
case 'th-TH':
case 'th-Th':
return (
formatted.replace(/(\d{4})/, (year) =>
(parseInt(year) - 543).toString(),
) + timeText
);
default:
return formatted + timeText;
}
}
/**
* @deprecated use dateFormatJS instead.
*/
export function dateFormat(
date?: string | Date | null,
fullmonth = false,
time = false,
number = false,
days = false,
) {
const m = moment(date);
if (!m.isValid()) return '';
if (time) return m.format('HH:mm');
if (number) return m.format('L');
const monthFormat = fullmonth ? 'MMMM' : 'MMM';
const formattedDate = m.format(
` ${days ? '' : 'DD'} ${monthFormat} YYYY ${time ? ' HH:mm' : ''}`,
);
return formattedDate;
}
function pad(n: number) {
return `${Math.floor(Math.abs(n))}`.padStart(2, '0');
}
function getTimezoneOffset(date: Date) {
const tzOffset = -date.getTimezoneOffset();
const diff = tzOffset >= 0 ? '+' : '-';
return diff + pad(tzOffset / 60) + ':' + pad(tzOffset % 60);
}
export function toISOStringWithTimezone(date: Date) {
return (
date.getFullYear() +
'-' +
pad(date.getMonth() + 1) +
'-' +
pad(date.getDate()) +
'T' +
pad(date.getHours()) +
':' +
pad(date.getMinutes()) +
':' +
pad(date.getSeconds()) +
getTimezoneOffset(date)
);
}
export function calculateAge(dt: Date | null | string): string;
export function calculateAge(
dt: Date | null | string,
only: 'year' | 'months' | 'days',
): number;
export function calculateAge(
dt: Date | null | string,
only?: 'year' | 'months' | 'days',
) {
if (!dt) return null;
const diff = Date.now() - new Date(dt).getTime();
const offset = new Date(diff);
const years = offset.getUTCFullYear() - 1970;
const months = offset.getUTCMonth();
const days = offset.getUTCDate() - 1;
switch (only) {
case 'year':
return years;
case 'months':
return months;
case 'days':
return days;
default:
}
switch (i18n.global.locale.value) {
case Lang.Thai:
return `${years} ปี ${months !== 0 ? months + ' เดือน' : ''} ${days !== 0 ? days + ' วัน' : ''}`;
default:
return `${years} years ${months !== 0 ? months + ' months' : ''} ${days !== 0 ? days + ' days' : ''} `;
}
}
export function disabledAfterToday(date: Date) {
const today = new Date();
today.setHours(0, 0, 0, 0);
return date > today;
}
/**
* This function accept date format from dd/MMM/YYYY and convert into date object
*/
export function parseAndFormatDate(value: string | number | undefined) {
if (!value) return;
if (value && value.toString().length === 10) {
const [date, month, year] = value.toString().split('/');
return new Date(`${year}-${month}-${date}T00:00:00.000Z`);
}
return null;
}