import moment, { Moment } from 'moment' import type { GenerateConfig } from 'rc-picker/lib/generate' export function getGenerateConfigWithUtcOffset( utcOffset: number ): GenerateConfig { if (utcOffset >= 16 || utcOffset <= -16) { throw Error('utcOffset is invalid.') } return { // get getNow: () => moment().utcOffset(utcOffset), getFixedDate: string => moment(string, 'YYYY-MM-DD').utcOffset(utcOffset, true), getEndDate: date => date.clone().utcOffset(utcOffset).endOf('month'), getWeekDay: date => { // weekday() + firstDayOfWeek() 结果跟语言无关,所以指定了一个确定存在的 locale const clone = date.clone().locale('en_US').utcOffset(utcOffset) return clone.weekday() + clone.localeData().firstDayOfWeek() }, getYear: date => date.clone().utcOffset(utcOffset).year(), getMonth: date => date.clone().utcOffset(utcOffset).month(), getDate: date => date.clone().utcOffset(utcOffset).date(), getHour: date => date.clone().utcOffset(utcOffset).hour(), getMinute: date => date.clone().utcOffset(utcOffset).minute(), getSecond: date => date.clone().utcOffset(utcOffset).second(), // set addYear: (date, diff) => date.clone().utcOffset(utcOffset).add(diff, 'year'), addMonth: (date, diff) => date.clone().utcOffset(utcOffset).add(diff, 'month'), addDate: (date, diff) => date.clone().utcOffset(utcOffset).add(diff, 'day'), setYear: (date, year) => date.clone().utcOffset(utcOffset).year(year), setMonth: (date, month) => date.clone().utcOffset(utcOffset).month(month), setDate: (date, num) => date.clone().utcOffset(utcOffset).date(num), setHour: (date, hour) => date.clone().utcOffset(utcOffset).hour(hour), setMinute: (date, minute) => date.clone().utcOffset(utcOffset).minute(minute), setSecond: (date, second) => date.clone().utcOffset(utcOffset).second(second), // compare isAfter: (date1, date2) => date1.isAfter(date2), isValidate: date => date.isValid(), locale: { getWeekFirstDay: locale => moment().locale(locale).localeData().firstDayOfWeek(), getWeekFirstDate: (locale, date) => date.clone().utcOffset(utcOffset).locale(locale).weekday(0), getWeek: (locale, date) => date.clone().utcOffset(utcOffset).locale(locale).week(), getShortWeekDays: locale => moment().locale(locale).localeData().weekdaysMin(), getShortMonths: locale => moment().locale(locale).localeData().monthsShort(), format: (locale, date, format) => date.clone().utcOffset(utcOffset).locale(locale).format(format), // copy from https://github.com/react-component/picker/blob/master/src/generate/moment.ts parse: (locale, text, formats) => { const fallbackFormatList: string[] = [] for (let i = 0; i < formats.length; i += 1) { let format = formats[i] let formatText = text if (format.includes('wo') || format.includes('Wo')) { format = format.replace(/wo/g, 'w').replace(/Wo/g, 'W') const matchFormat = format.match(/[-YyMmDdHhSsWwGg]+/g) const matchText = formatText.match(/[-\d]+/g) if (matchFormat && matchText) { format = matchFormat.join('') formatText = matchText.join('') } else { fallbackFormatList.push(format.replace(/o/g, '')) } } const date = moment(formatText, format, locale, true).utcOffset(utcOffset, true) if (date.isValid()) { return date } } // Fallback to fuzzy matching, this should always not reach match or need fire a issue for (let i = 0; i < fallbackFormatList.length; i += 1) { const date = moment(text, fallbackFormatList[i], locale, false).utcOffset(utcOffset, true) if (date.isValid()) { return date } } return null } } } }