Files
psp_panel/src/app/utils/date-formatter.utils.ts
T
2026-03-29 18:07:10 +03:30

343 lines
10 KiB
TypeScript

import jalaliPlugin from '@zoomit/dayjs-jalali-plugin';
import dayjs, { Dayjs } from 'dayjs';
import 'dayjs/locale/fa';
import relativeTime from 'dayjs/plugin/relativeTime';
// Extend dayjs with plugins
dayjs.extend(jalaliPlugin);
dayjs.extend(relativeTime);
/**
* Common date format patterns for Jalali calendar
*/
export const JALALI_DATE_FORMATS = {
/** Full date with weekday: "پنج‌شنبه، ۱۳ شهریور ۱۳۹۷" */
FULL_WITH_WEEKDAY: 'dddd، DD MMMM YYYY',
/** Full date: "۱۳ شهریور ۱۳۹۷" */
FULL: 'DD MMMM YYYY',
/** Short date with month name: "۱۳ شهریور ۹۷" */
SHORT: 'DD MMMM YY',
/** Numeric date: "۱۳۹۷/۰۶/۱۳" */
NUMERIC: 'YYYY/MM/DD',
/** Numeric date with time: "۱۳۹۷/۰۶/۱۳ ۱۶:۳۰" */
NUMERIC_WITH_TIME: 'YYYY/MM/DD HH:mm',
/** Numeric date with full time: "۱۳۹۷/۰۶/۱۳ ۱۶:۳۰:۱۵" */
NUMERIC_WITH_FULL_TIME: 'YYYY/MM/DD HH:mm:ss',
/** Time only: "۱۶:۳۰" */
TIME: 'HH:mm',
/** Time with seconds: "۱۶:۳۰:۱۵" */
TIME_WITH_SECONDS: 'HH:mm:ss',
/** Month and year: "شهریور ۱۳۹۷" */
MONTH_YEAR: 'MMMM YYYY',
/** Day and month: "۱۳ شهریور" */
DAY_MONTH: 'DD MMMM',
} as const;
/**
* Common date format patterns for Gregorian calendar
*/
export const GREGORIAN_DATE_FORMATS = {
/** Full date with weekday: "Thursday, September 04 2018" */
FULL_WITH_WEEKDAY: 'dddd, MMMM DD YYYY',
/** Full date: "September 04 2018" */
FULL: 'MMMM DD YYYY',
/** Short date: "Sep 04 18" */
SHORT: 'MMM DD YY',
/** Numeric date: "2018-09-04" */
NUMERIC: 'YYYY-MM-DD',
/** Numeric date with time: "2018-09-04 16:30" */
NUMERIC_WITH_TIME: 'YYYY-MM-DD HH:mm',
/** Numeric date with full time: "2018-09-04 16:30:15" */
NUMERIC_WITH_FULL_TIME: 'YYYY-MM-DD HH:mm:ss',
/** Time only: "16:30" */
TIME: 'HH:mm',
/** Time with seconds: "16:30:15" */
TIME_WITH_SECONDS: 'HH:mm:ss',
/** Month and year: "September 2018" */
MONTH_YEAR: 'MMMM YYYY',
/** Day and month: "September 04" */
DAY_MONTH: 'MMMM DD',
} as const;
/**
* Format a date as Jalali (Persian) calendar in Farsi locale
*
* @param date - Date to format (string, Date, Dayjs, or timestamp)
* @param format - Format pattern (default: 'YYYY/MM/DD')
* @returns Formatted date string in Jalali calendar
*
* @example
* formatJalali('2018-09-04') // '1397/06/13'
* formatJalali('2018-09-04', JALALI_DATE_FORMATS.FULL) // '۱۳ شهریور ۱۳۹۷'
* formatJalali(new Date(), JALALI_DATE_FORMATS.FULL_WITH_WEEKDAY) // 'پنج‌شنبه، ۱۳ شهریور ۱۳۹۷'
*/
export function formatJalali(
date: string | Date | Dayjs | number,
format: string = JALALI_DATE_FORMATS.NUMERIC,
): string {
return dayjs(date).calendar('jalali').locale('fa').format(format);
}
/**
* Format a date as Gregorian calendar in English locale
*
* @param date - Date to format (string, Date, Dayjs, or timestamp)
* @param format - Format pattern (default: 'YYYY-MM-DD')
* @returns Formatted date string in Gregorian calendar
*
* @example
* formatGregorian('1397/06/13', GREGORIAN_DATE_FORMATS.FULL) // 'September 04 2018'
* formatGregorian(new Date(), GREGORIAN_DATE_FORMATS.NUMERIC_WITH_TIME) // '2018-09-04 16:30'
*/
export function formatGregorian(
date: string | Date | Dayjs | number,
format: string = GREGORIAN_DATE_FORMATS.NUMERIC,
): string {
return dayjs(date).calendar('gregory').locale('en').format(format);
}
/**
* Parse a Jalali date string and return a Dayjs instance
*
* @param jalaliDate - Jalali date string (e.g., '1398-10-17')
* @param format - Optional format pattern for parsing
* @returns Dayjs instance
*
* @example
* parseJalali('1398-10-17') // Dayjs instance
* parseJalali('1398/10/17') // Dayjs instance
*/
export function parseJalali(jalaliDate: string, format?: string): Dayjs {
return dayjs(jalaliDate, { jalali: true, ...(format && { format }) });
}
/**
* Convert a Gregorian date to Jalali format
*
* @param gregorianDate - Gregorian date string, Date object, or Dayjs instance
* @param format - Optional format pattern (default: 'YYYY/MM/DD')
* @returns Formatted Jalali date string
*
* @example
* gregorianToJalali('2018-09-04') // '1397/06/13'
* gregorianToJalali('2018-09-04', JALALI_DATE_FORMATS.FULL) // '۱۳ شهریور ۱۳۹۷'
*/
export function gregorianToJalali(
gregorianDate: string | Date | Dayjs,
format: string = JALALI_DATE_FORMATS.NUMERIC,
): string {
return dayjs(gregorianDate).calendar('jalali').locale('fa').format(format);
}
/**
* Convert a Jalali date to Gregorian format
*
* @param jalaliDate - Jalali date string (e.g., '1398-10-17')
* @param format - Optional format pattern (default: 'YYYY-MM-DD')
* @returns Formatted Gregorian date string
*
* @example
* jalaliToGregorian('1398-10-17') // '2020-01-07'
* jalaliToGregorian('1397/06/13', GREGORIAN_DATE_FORMATS.FULL) // 'September 04 2018'
*/
export function jalaliToGregorian(
jalaliDate: string,
format: string = GREGORIAN_DATE_FORMATS.NUMERIC,
): string {
return parseJalali(jalaliDate).calendar('gregory').locale('en').format(format);
}
/**
* Get current date and time in Jalali format
*
* @param format - Optional format pattern (default: 'YYYY/MM/DD HH:mm')
* @returns Current date and time in Jalali format
*
* @example
* nowJalali() // '1403/12/05 14:30'
* nowJalali(JALALI_DATE_FORMATS.FULL_WITH_WEEKDAY) // 'یکشنبه، ۵ اسفند ۱۴۰۳'
*/
export function nowJalali(format: string = JALALI_DATE_FORMATS.NUMERIC_WITH_TIME): string {
return dayjs().calendar('jalali').locale('fa').format(format);
}
/**
* Get current date and time in Gregorian format
*
* @param format - Optional format pattern (default: 'YYYY-MM-DD HH:mm')
* @returns Current date and time in Gregorian format
*
* @example
* nowGregorian() // '2026-02-24 14:30'
* nowGregorian(GREGORIAN_DATE_FORMATS.FULL_WITH_WEEKDAY) // 'Sunday, February 24 2026'
*/
export function nowGregorian(format: string = GREGORIAN_DATE_FORMATS.NUMERIC_WITH_TIME): string {
return dayjs().calendar('gregory').locale('en').format(format);
}
/**
* Format a time duration as a relative time string in Farsi
*
* @param date - Date to compare against current time
* @returns Relative time string in Farsi
*
* @example
* relativeTimeJalali(dayjs().subtract(2, 'day')) // '۲ روز پیش'
*/
export function relativeTimeJalali(date: string | Date | Dayjs | number): string {
return dayjs(date).locale('fa').fromNow();
}
/**
* Check if a date string is a valid Jalali date
*
* @param jalaliDate - Jalali date string
* @returns true if valid, false otherwise
*
* @example
* isValidJalaliDate('1398-10-17') // true
* isValidJalaliDate('1398-13-17') // false
*/
export function isValidJalaliDate(jalaliDate: string): boolean {
return parseJalali(jalaliDate).isValid();
}
/**
* Get the start of day for a date in Jalali calendar
*
* @param date - Date to get start of day for
* @returns Dayjs instance at start of day
*
* @example
* startOfDayJalali('1398-10-17') // Dayjs instance at 00:00:00
*/
export function startOfDayJalali(date: string | Date | Dayjs | number): Dayjs {
return dayjs(date).calendar('jalali').startOf('day');
}
/**
* Get the end of day for a date in Jalali calendar
*
* @param date - Date to get end of day for
* @returns Dayjs instance at end of day
*
* @example
* endOfDayJalali('1398-10-17') // Dayjs instance at 23:59:59
*/
export function endOfDayJalali(date: string | Date | Dayjs | number): Dayjs {
return dayjs(date).calendar('jalali').endOf('day');
}
/**
* Format a date with custom calendar and locale
*
* @param date - Date to format
* @param calendar - Calendar type ('jalali' | 'gregory')
* @param locale - Locale ('fa' | 'en')
* @param format - Format pattern
* @returns Formatted date string
*
* @example
* formatDate('2018-09-04', 'jalali', 'fa', 'DD MMMM YYYY') // '۱۳ شهریور ۱۳۹۷'
* formatDate('2018-09-04', 'gregory', 'en', 'MMMM DD YYYY') // 'September 04 2018'
*/
export function formatDate(
date: string | Date | Dayjs | number,
calendar: 'jalali' | 'gregory',
locale: 'fa' | 'en',
format: string,
): string {
return dayjs(date).calendar(calendar).locale(locale).format(format);
}
/**
* Get Jalali month name in Farsi
*
* @param monthNumber - Month number (1-12)
* @returns Month name in Farsi
*
* @example
* getJalaliMonthName(1) // 'فروردین'
* getJalaliMonthName(6) // 'شهریور'
*/
export function getJalaliMonthName(monthNumber: number): string {
const monthNames = [
'فروردین',
'اردیبهشت',
'خرداد',
'تیر',
'مرداد',
'شهریور',
'مهر',
'آبان',
'آذر',
'دی',
'بهمن',
'اسفند',
];
return monthNames[monthNumber - 1] || '';
}
/**
* Get Jalali weekday name in Farsi
*
* @param dayNumber - Day number (0-6, where 0 is Saturday)
* @returns Weekday name in Farsi
*
* @example
* getJalaliWeekdayName(0) // 'شنبه'
* getJalaliWeekdayName(4) // 'چهارشنبه'
*/
export function getJalaliWeekdayName(dayNumber: number): string {
const weekdayNames = ['شنبه', 'یکشنبه', 'دوشنبه', 'سه‌شنبه', 'چهارشنبه', 'پنج‌شنبه', 'جمعه'];
return weekdayNames[dayNumber] || '';
}
export function jalaliDiff(
date1: string | number | Date | Dayjs,
date2: string | number | Date | Dayjs,
unit: dayjs.OpUnitType = 'day',
): number {
return toJalali(date1).diff(toJalali(date2), unit);
}
export function isJalaliBefore(
date1: string | number | Date | Dayjs,
date2: string | number | Date | Dayjs,
): boolean {
return toJalali(date1).isBefore(toJalali(date2));
}
export function isJalaliAfter(
date1: string | number | Date | Dayjs,
date2: string | number | Date | Dayjs,
): boolean {
return toJalali(date1).isAfter(toJalali(date2));
}
export function toJalali(date: string | number | Date | Dayjs, format = 'YYYY/MM/DD'): Dayjs {
return dayjs(date).calendar('jalali');
}
export default {
formatJalali,
formatGregorian,
parseJalali,
gregorianToJalali,
jalaliToGregorian,
nowJalali,
nowGregorian,
relativeTimeJalali,
isValidJalaliDate,
startOfDayJalali,
endOfDayJalali,
formatDate,
getJalaliMonthName,
getJalaliWeekdayName,
jalaliDiff,
isJalaliBefore,
isJalaliAfter,
JALALI_DATE_FORMATS,
GREGORIAN_DATE_FORMATS,
};