diff --git a/components/vc-picker/generate/dataFns.ts b/components/vc-picker/generate/dataFns.ts new file mode 100644 index 000000000..196f8d7ec --- /dev/null +++ b/components/vc-picker/generate/dataFns.ts @@ -0,0 +1,115 @@ +import { + getDay, + getYear, + getMonth, + getDate, + endOfMonth, + getHours, + getMinutes, + getSeconds, + addYears, + addMonths, + addDays, + setYear, + setMonth, + setDate, + setHours, + setMinutes, + setSeconds, + isAfter, + isValid, + getWeek, + startOfWeek, + format as formatDate, + parse as parseDate, +} from 'date-fns'; +import * as Locale from 'date-fns/locale'; +import type { GenerateConfig } from '.'; + +const dealLocal = (str: string) => { + return str.replace(/_/g, ''); +}; + +const localeParse = (format: string) => { + return format + .replace(/Y/g, 'y') + .replace(/D/g, 'd') + .replace(/gggg/, 'yyyy') + .replace(/g/g, 'G') + .replace(/([Ww])o/g, 'wo'); +}; + +const generateConfig: GenerateConfig = { + // get + getNow: () => new Date(), + getFixedDate: string => new Date(string), + getEndDate: date => endOfMonth(date), + getWeekDay: date => getDay(date), + getYear: date => getYear(date), + getMonth: date => getMonth(date), + getDate: date => getDate(date), + getHour: date => getHours(date), + getMinute: date => getMinutes(date), + getSecond: date => getSeconds(date), + + // set + addYear: (date, diff) => addYears(date, diff), + addMonth: (date, diff) => addMonths(date, diff), + addDate: (date, diff) => addDays(date, diff), + setYear: (date, year) => setYear(date, year), + setMonth: (date, month) => setMonth(date, month), + setDate: (date, num) => setDate(date, num), + setHour: (date, hour) => setHours(date, hour), + setMinute: (date, minute) => setMinutes(date, minute), + setSecond: (date, second) => setSeconds(date, second), + + // Compare + isAfter: (date1, date2) => isAfter(date1, date2), + isValidate: date => isValid(date), + + locale: { + getWeekFirstDay: locale => { + const clone = Locale[dealLocal(locale)]; + return clone.options.weekStartsOn; + }, + getWeekFirstDate: (locale, date) => { + return startOfWeek(date, { locale: Locale[dealLocal(locale)] }); + }, + getWeek: (locale, date) => { + return getWeek(date, { locale: Locale[dealLocal(locale)] }); + }, + getShortWeekDays: locale => { + const clone = Locale[dealLocal(locale)]; + return Array.from({ length: 7 }).map((_, i) => clone.localize.day(i, { width: 'short' })); + }, + getShortMonths: locale => { + const clone = Locale[dealLocal(locale)]; + return Array.from({ length: 12 }).map((_, i) => + clone.localize.month(i, { width: 'abbreviated' }), + ); + }, + format: (locale, date, format) => { + if (!isValid(date)) { + return null; + } + return formatDate(date, localeParse(format), { + locale: Locale[dealLocal(locale)], + }); + }, + parse: (locale, text, formats) => { + for (let i = 0; i < formats.length; i += 1) { + const format = localeParse(formats[i]); + const formatText = text; + const date = parseDate(formatText, format, new Date(), { + locale: Locale[dealLocal(locale)], + }); + if (isValid(date)) { + return date; + } + } + return null; + }, + }, +}; + +export default generateConfig; diff --git a/components/vc-picker/generate/dayjs.ts b/components/vc-picker/generate/dayjs.ts index 702ae0018..ff6c4b16e 100644 --- a/components/vc-picker/generate/dayjs.ts +++ b/components/vc-picker/generate/dayjs.ts @@ -76,23 +76,11 @@ const generateConfig: GenerateConfig = { isValidate: date => date.isValid(), locale: { - getWeekFirstDay: locale => - dayjs() - .locale(parseLocale(locale)) - .localeData() - .firstDayOfWeek(), + getWeekFirstDay: locale => dayjs().locale(parseLocale(locale)).localeData().firstDayOfWeek(), getWeekFirstDate: (locale, date) => date.locale(parseLocale(locale)).weekday(0), getWeek: (locale, date) => date.locale(parseLocale(locale)).week(), - getShortWeekDays: locale => - dayjs() - .locale(parseLocale(locale)) - .localeData() - .weekdaysMin(), - getShortMonths: locale => - dayjs() - .locale(parseLocale(locale)) - .localeData() - .monthsShort(), + getShortWeekDays: locale => dayjs().locale(parseLocale(locale)).localeData().weekdaysMin(), + getShortMonths: locale => dayjs().locale(parseLocale(locale)).localeData().monthsShort(), format: (locale, date, format) => date.locale(parseLocale(locale)).format(format), parse: (locale, text, formats) => { const localeStr = parseLocale(locale); @@ -103,9 +91,7 @@ const generateConfig: GenerateConfig = { // parse Wo const year = formatText.split('-')[0]; const weekStr = formatText.split('-')[1]; - const firstWeek = dayjs(year, 'YYYY') - .startOf('year') - .locale(localeStr); + const firstWeek = dayjs(year, 'YYYY').startOf('year').locale(localeStr); for (let j = 0; j <= 52; j += 1) { const nextWeek = firstWeek.add(j, 'week'); if (nextWeek.format('Wo') === weekStr) { diff --git a/components/vc-picker/generate/index.ts b/components/vc-picker/generate/index.ts new file mode 100644 index 000000000..b0cd56d5e --- /dev/null +++ b/components/vc-picker/generate/index.ts @@ -0,0 +1,44 @@ +export type GenerateConfig = { + // Get + getWeekDay: (value: DateType) => number; + getSecond: (value: DateType) => number; + getMinute: (value: DateType) => number; + getHour: (value: DateType) => number; + getDate: (value: DateType) => number; + getMonth: (value: DateType) => number; + getYear: (value: DateType) => number; + getNow: () => DateType; + getFixedDate: (fixed: string) => DateType; + getEndDate: (value: DateType) => DateType; + + // Set + addYear: (value: DateType, diff: number) => DateType; + addMonth: (value: DateType, diff: number) => DateType; + addDate: (value: DateType, diff: number) => DateType; + setYear: (value: DateType, year: number) => DateType; + setMonth: (value: DateType, month: number) => DateType; + setDate: (value: DateType, date: number) => DateType; + setHour: (value: DateType, hour: number) => DateType; + setMinute: (value: DateType, minute: number) => DateType; + setSecond: (value: DateType, second: number) => DateType; + + // Compare + isAfter: (date1: DateType, date2: DateType) => boolean; + isValidate: (date: DateType) => boolean; + + locale: { + getWeekFirstDay: (locale: string) => number; + getWeekFirstDate: (locale: string, value: DateType) => DateType; + getWeek: (locale: string, value: DateType) => number; + + format: (locale: string, date: DateType, format: string) => string; + + /** Should only return validate date instance */ + parse: (locale: string, text: string, formats: string[]) => DateType | null; + + /** A proxy for getting locale with moment or other locale library */ + getShortWeekDays?: (locale: string) => string[]; + /** A proxy for getting locale with moment or other locale library */ + getShortMonths?: (locale: string) => string[]; + }; +}; diff --git a/package.json b/package.json index 7db46b41e..d2e585dca 100644 --- a/package.json +++ b/package.json @@ -208,6 +208,8 @@ "@simonwep/pickr": "~1.8.0", "array-tree-filter": "^2.1.0", "async-validator": "^3.3.0", + "date-fns": "^2.22.1", + "dayjs": "^1.10.5", "dom-align": "^1.12.1", "dom-scroll-into-view": "^2.0.0", "lodash": "^4.17.21",