import { isValidDate, getPureDate } from "@web3r/flowerkit/date"; import { eachYearOfInterval, format, parse } from "date-fns"; import { IMask } from "react-imask"; import type { TMaskOptions } from "../../maskedInput"; import type { TUserUnionValues, IDatePicker, TCustomMaskArg, TValidDateSingleStamp, } from "../config/types"; /** * Получает экземпляр Date из значения * @returns {TValidDateSingleStamp} */ const getDateInstance = (userValue?: TUserUnionValues, isNormalize: boolean = true): TValidDateSingleStamp => { const getDate = (val: number | string | Date) => { const stamp = new Date(val); if (isNormalize && isValidDate(stamp)) { stamp.setSeconds(0); stamp.setMilliseconds(0); } return stamp; }; switch (true) { // дата уже валидна case isValidDate(userValue): { return isNormalize ? getDate(userValue as Date) : userValue as Date; } // передано число case typeof userValue === "number": { const dateFromNumber = getDate(userValue as number); return isValidDate(dateFromNumber) ? dateFromNumber : null; } // передана строка case typeof userValue === "string" && !!userValue.length: { if (userValue === "today") { return getDate(new Date()); } else { const dateFromStr = getDate(userValue); return isValidDate(dateFromStr) ? dateFromStr : null; } } // передан массив case getIsValidRange(userValue): { const [ startDate ] = userValue as unknown as Date[]; return getDateInstance(startDate); } // что-то не так default: { return null; } } }; /** * Проверяет валидность переданного промежутка дат * @returns {boolean} */ const getIsValidRange = (value?: TUserUnionValues): boolean => { return Array.isArray(value) && value.length === 2 && value.every((val) => isValidDate(getDateInstance(val))); }; /** * Получает дату с актуальным временем пользователя * @param date{TValidDateSingleStamp} * @returns {TValidDateSingleStamp} */ const getDateWithLocalTime = (date: TValidDateSingleStamp): TValidDateSingleStamp => { if (isValidDate(date)) { const now = new Date(); const hh = now.getHours(); const mm = now.getMinutes(); const ss = now.getSeconds(); const ms = now.getMilliseconds(); (date as Date).setHours(hh); (date as Date).setMinutes(mm); (date as Date).setSeconds(ss); (date as Date).setMilliseconds(ms); } return date; }; /** * Получает ISO-штамп из значения * @param value{*} * @param isSetUserLocalTime{Boolean=} * @returns {string} */ const getStrFromDate = (value: unknown, isSetUserLocalTime: boolean = false): string => { if (isValidDate(value)) { if (isSetUserLocalTime) { value = getDateWithLocalTime(value as Date); } return (value as Date).toString(); } else { return ""; } }; /** * Возвращает формат даты - со временем или без него * @returns {string} */ const getDateFormat = (isTimeSelect: IDatePicker["isTime"], dateFormat: Required, timeFormat: IDatePicker["timeFormat"]): string => { return isTimeSelect ? `${dateFormat} ${timeFormat}` : dateFormat!; }; /** * Возвращает результат выполнения функции как Promise * @param fn{Function} * @returns {Promise} */ const getAsyncFn = async (fn: Function): Promise => { try { return await fn(); } catch { return Promise.resolve(fn()); } }; /** * Получает массив годов * @returns {Date[]} */ const getYearsRange = (fromDate?: Date, toDate?: Date): Date[] => { if (isValidDate(fromDate) && isValidDate(toDate)) { return eachYearOfInterval({ start: fromDate!, end: toDate!, }); } else { return []; } }; /** * Получает дату со сброшенными часами и минутами * @returns {Date} */ const getClearDate = (date: Date | null | undefined = new Date()): Date => { const value = isValidDate(date) ? date : new Date(); return getPureDate(value)!; }; /** * Получает значение поля калердаря * @returns {string} */ const getStrFromStamp = (value: TUserUnionValues, isTime = false): string => { switch (true) { case Array.isArray(value): { const [ start, end ] = value; if (start && end) { return `${getStrFromDate(start, !isTime)}, ${getStrFromDate(end, !isTime)}`; } else { return getStrFromDate(start, !isTime); } } case !value: { return ""; } default: { return getStrFromDate(value, !isTime); } } }; /** * Получает стандартную маску для поля календаря * @returns {TMaskOptions} */ const getDefaultMask = ({ maxDate, minDate, format: maskFormat, isTime, isRange, isAutoFix, today, }: TCustomMaskArg): TMaskOptions => { return { mask: Date, lazy: true, pattern: isTime ? "d`.m`.Y `HH:`MM" : "d`.m`.Y", blocks: { d: { mask: IMask.MaskedRange, from: 1, to: 31, maxLength: 2, autofix: "pad", }, m: { mask: IMask.MaskedRange, from: 1, to: 12, maxLength: 2, autofix: "pad", }, Y: { mask: IMask.MaskedRange, from: minDate?.getFullYear(), to: maxDate?.getFullYear(), maxLength: 4, autofix: minDate?.getFullYear() !== maxDate?.getFullYear(), }, HH: { mask: IMask.MaskedRange, from: 0, to: 23, maxLength: 2, autofix: "pad", }, MM: { mask: IMask.MaskedRange, from: 0, to: 59, maxLength: 2, }, }, format: (date: Date) => isValidDate(date) ? format(date, maskFormat) : "", parse: (value: string) => parse(value, maskFormat, today), }; }; export { getAsyncFn, getClearDate, getDateFormat, getDateInstance, getDateWithLocalTime, getDefaultMask, getIsValidRange, getStrFromDate, getStrFromStamp, getYearsRange, };