You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome 88以下版本Day.js识别DST异常问题求助

Day.js在Chrome 88及以下版本夏令时识别问题的解决方案

我们计划引入Day.js处理夏令时(DST),该工具在现代浏览器中表现正常,但在Chrome 88及以下版本的旧浏览器中无法正确识别DST。测试用的React应用代码如下:

import { useState, useEffect } from 'react';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);

const defaultTimezone = "Africa/Cairo";

const events = [
  { date: '2024-04-20', time: '20:00', description: 'Event 1', timezone: defaultTimezone },
  { date: '2024-04-30', time: '20:00', description: 'Event 2', timezone: defaultTimezone },
  { date: '2024-06-05', time: '20:00', description: 'Event 3', timezone: defaultTimezone },
  { date: '2024-09-20', time: '20:00', description: 'Event 4', timezone: defaultTimezone },
  { date: '2024-10-20', time: '20:00', description: 'Event 5', timezone: defaultTimezone },
  { date: '2024-11-20', time: '20:00', description: 'Event 6', timezone: defaultTimezone },
];

function App() {
  const [formattedEvents, setFormattedEvents] = useState([]);

  useEffect(() => {
    const formattedEvents = events.map(event => {
      const cairoDateTime = dayjs.tz(`${event.date}T${event.time}`, event.timezone);
      const berlinDateTime = cairoDateTime.clone().tz('Europe/Berlin');
      
      const formattedCairoDateTime = cairoDateTime.format('YYYY-MM-DD HH:mm:ss');
      const formattedBerlinDateTime = berlinDateTime.format('YYYY-MM-DD HH:mm:ss');

      return {
        ...event,
        cairoDateTime: formattedCairoDateTime,
        berlinDateTime: formattedBerlinDateTime
      };
    });
    setFormattedEvents(formattedEvents);
  }, []);

  return (
    <div className="App">
      <header className="App-header">
        <h2>Events</h2>
        <ul>
          {formattedEvents.map((event, index) => (
            <li key={index}>
              {event.description}: 
              <ul>
                <li>Cairo Time: {event.cairoDateTime} ({event.timezone})</li>
                <li>Berlin Time: {event.berlinDateTime} (Europe/Berlin)</li>
              </ul>
            </li>
          ))}
        </ul>
      </header>
    </div>
  );
}

export default App;

输出差异

现代浏览器(符合预期)

Events
Event 1:
Cairo Time: 2024-04-20 20:00:00 (Africa/Cairo)
Berlin Time: 2024-04-20 20:00:00 (Europe/Berlin)
Event 2:
Cairo Time: 2024-04-30 20:00:00 (Africa/Cairo)
Berlin Time: 2024-04-30 19:00:00 (Europe/Berlin)
Event 3:
Cairo Time: 2024-06-05 20:00:00 (Africa/Cairo)
Berlin Time: 2024-06-05 19:00:00 (Europe/Berlin)
Event 4:
Cairo Time: 2024-09-20 20:00:00 (Africa/Cairo)
Berlin Time: 2024-09-20 19:00:00 (Europe/Berlin)
Event 5:
Cairo Time: 2024-10-20 20:00:00 (Africa/Cairo)
Berlin Time: 2024-10-20 19:00:00 (Europe/Berlin)
Event 6:
Cairo Time: 2024-11-20 20:00:00 (Africa/Cairo)
Berlin Time: 2024-11-20 19:00:00 (Europe/Berlin)

Chrome 88及以下版本(DST识别错误)

Events
Event 1:
Cairo Time: 2024-04-20 20:00:00 (Africa/Cairo)
Berlin Time: 2024-04-20 20:00:00 (Europe/Berlin)
Event 2:
Cairo Time: 2024-04-30 20:00:00 (Africa/Cairo)
Berlin Time: 2024-04-30 20:00:00 (Europe/Berlin)
Event 3:
Cairo Time: 2024-06-05 20:00:00 (Africa/Cairo)
Berlin Time: 2024-06-05 20:00:00 (Europe/Berlin)
Event 4:
Cairo Time: 2024-09-20 20:00:00 (Africa/Cairo)
Berlin Time: 2024-09-20 20:00:00 (Europe/Berlin)
Event 5:
Cairo Time: 2024-10-20 20:00:00 (Africa/Cairo)
Berlin Time: 2024-10-20 20:00:00 (Europe/Berlin)
Event 6:
Cairo Time: 2024-11-20 20:00:00 (Africa/Cairo)
Berlin Time: 2024-11-20 19:00:00 (Europe/Berlin)

解决方案

1. 引入customParseFormat插件并显式指定解析格式

旧版本Chrome的Intl API时区数据不全,Day.js默认依赖该API导致DST识别错误。通过引入customParseFormat插件,显式指定日期时间格式,强制Day.js按规则解析时区:

首先安装插件:

npm install dayjs-plugin-custom-parse-format

修改代码:

import { useState, useEffect } from 'react';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import customParseFormat from 'dayjs/plugin/customParseFormat';

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(customParseFormat);

const defaultTimezone = "Africa/Cairo";
const dateTimeFormat = 'YYYY-MM-DDTHH:mm'; // 显式指定输入格式

// ... 其余events定义不变

function App() {
  const [formattedEvents, setFormattedEvents] = useState([]);

  useEffect(() => {
    const formattedEvents = events.map(event => {
      // 使用指定格式解析,确保时区规则生效
      const cairoDateTime = dayjs.tz(`${event.date}T${event.time}`, dateTimeFormat, event.timezone);
      const berlinDateTime = cairoDateTime.clone().tz('Europe/Berlin');
      
      const formattedCairoDateTime = cairoDateTime.format('YYYY-MM-DD HH:mm:ss');
      const formattedBerlinDateTime = berlinDateTime.format('YYYY-MM-DD HH:mm:ss');

      return {
        ...event,
        cairoDateTime: formattedCairoDateTime,
        berlinDateTime: formattedBerlinDateTime
      };
    });
    setFormattedEvents(formattedEvents);
  }, []);

  // ... 其余组件代码不变
}

export default App;

2. 使用包含完整时区数据的Day.js构建包

Day.js的默认timezone插件依赖宿主环境的Intl API,旧浏览器的时区数据可能过时。改用包含完整IANA时区数据库的Day.js构建版本,不依赖浏览器API:

安装完整版本:

npm install dayjs-with-timezone

修改导入代码:

// 替换原有的dayjs及插件导入
import dayjs from 'dayjs-with-timezone';

// 无需单独引入utc和timezone插件,完整版本已包含
const defaultTimezone = "Africa/Cairo";

// ... 其余代码不变

3. 降级Day.js到兼容旧浏览器的稳定版本

部分新版本Day.js优化了现代浏览器支持,但牺牲了旧环境兼容性。尝试降级到v1.11.x版本(该版本对旧浏览器兼容性更好):

npm install dayjs@1.11.10

重新运行测试,验证夏令时识别是否恢复正常。


内容的提问来源于stack exchange,提问作者Sebo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:34:59