antd 1.x datepicker 时区问题

Antd(1.x stable) - DatePicker

依赖关系

  • 底层引用了 rc-calender(~5.6.2)

  • 封装过程中使用了wrapPicker方法和createPicker方法

    const DatePicker = wrapPicker(createPicker(RcCalendar));
    const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'yyyy-MM');
  • DatePicker的Date处理函数,依赖gregorian-calendar(4.1.0)

  • gregorian-calendar内置了en_USzh_CN两个locale配置文件,内置的时间处理对象GregorianCalendar默认使用en_US.

    antd全局以及各组件配置了不同的locale,分别处理不同的场景,但是DatePicker最底层是直接使用了gregorian-calendar中的配置

    /*
     * en-us locale
     * @ignore
     * @author yiminghe@gmail.com
     */
    module.exports = {
      // in minutes
      timezoneOffset: -8 * 60,
      firstDayOfWeek: 0,
      minimalDaysInFirstWeek: 1,
    };
    /*
     * zh-cn locale
     * @ignore
     * @author yiminghe@gmail.com
     */
    module.exports = {
      // in minutes
      timezoneOffset: 8 * 60,
      firstDayOfWeek: 1,
      minimalDaysInFirstWeek: 1,
    };

代码逻辑分析

  • wrapPicker方法默认传递一些参数给createPicker默认传入zh_CN。同时会从antd的全局locale方法中寻找DatePicker的locale配置

  • createPicker将props传入的locale,传递给GregorianCalendar对象生成基本的locale信息

  • rc-calender根据locale信息进行组件渲染

核心问题

  • 1.x 的antd datepick在使用时,不根据用户的new Date().timezoneOffset设置日期,而是根据默认的local配置进行设置。分析过程见上述“代码逻辑分析”

  • 外层的antd的LocaleProvider包装组件会修改全局的locale,因此双语切换时,会存在用户的datepicker组件时区被改写的问题

解决方案

  • wrapPicker方法中会从全局的antLocale.DatePicker locale配置,将此处的timezoneOffset覆写即可

深入LocaleProvider的配置

LocaleProvider的使用

locale的配置,以en_US为例

Last updated

Was this helpful?