使用React DayPicker与date-fns-jalali:日历为何从每月11日而非1日开始?
解决React DayPicker结合date-fns-jalali时日历从11日开始的问题
问题根源
你遇到的日历偏移问题,核心是公历与贾拉利历的日期逻辑混用:
- 导入的
faIR是date-fns的公历波斯语本地化包,而非date-fns-jalali的贾拉利历本地化 - DayPicker默认基于公历计算月份起始和日期分布,而你用date-fns-jalali的方法处理日期,导致日期渲染错位
fromDate设置的是贾拉利历的当月起始,但DayPicker仍按公历逻辑解析日期范围
修复方案
以下是调整后的完整代码,关键修改点已标注:
import * as React from "react"; import { DayPicker, DayPickerDefaultProps } from "react-day-picker"; // 替换为date-fns-jalali的locale,而非date-fns的 import { faIR } from "date-fns-jalali/locale"; // 确保所有日期处理方法都来自date-fns-jalali import { format, getMonth, getYear, startOfMonth } from "date-fns-jalali"; type CalendarProps = Partial<DayPickerDefaultProps>; function Calendar({ ...props }: CalendarProps) { const jalaliMonths: string[] = [ "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند" ]; const jalaliFormatters: DayPickerDefaultProps["formatters"] = { formatWeekdayName: (date: Date) => format(date, "EEEEEE", { locale: faIR }), formatCaption: (date: Date) => { // getMonth和getYear都是date-fns-jalali的方法,返回贾拉利历的月份/年份 const month = getMonth(date); const year = getYear(date); return `${jalaliMonths[month]} ${year}`; }, formatDay: (date: Date) => format(date, "d", { locale: faIR }), }; const today = new Date(); // 获取贾拉利历的当月起始日期 const firstOfJalaliMonth = startOfMonth(today); return ( <DayPicker // 移除fromDate,改用month指定当前渲染的贾拉利历月份 month={firstOfJalaliMonth} dir="rtl" formatters={jalaliFormatters} locale={faIR} // 波斯历每周从周六开始,设置weekStartsOn为6(周日是0,周六是6) weekStartsOn={6} {...props} /> ); }
关键修改说明
- Locale替换:使用
date-fns-jalali/locale下的faIR,确保本地化规则适配贾拉利历 - 日期范围控制:用
month属性指定要渲染的贾拉利历月份,而非fromDate限制起始日期,让DayPicker正确渲染该月的所有日期 - 周起始设置:波斯历每周以周六为第一天,设置
weekStartsOn={6}保证周显示顺序正确 - 统一方法来源:所有日期处理方法(
format/getMonth/getYear/startOfMonth)均来自date-fns-jalali,避免公历与贾拉利历逻辑冲突
内容的提问来源于stack exchange,提问作者Mohamad Sajadi
相关产品推荐
相关产品推荐

