date-fns/date-fns-tz埃及等国DST时间计算错误技术问询
夏令时(凌晨12点生效)时区的UTC转换错误问题
问题背景
针对夏令时(DST)于凌晨12点开始的国家(如黎巴嫩、古巴、埃及),使用date-fns和date-fns-tz进行UTC日期转换时出现计算错误。
使用的库版本
date-fns: 2.30.0date-fns-tz: 1.3.8
现有实现代码
const dstSdate = '2024-04-26'; const dstEdate = '2024-10-31'; // Format the date to include the UTC offset const sformattedDateWithOffset = format( zonedTimeToUtc(startOfDay(new Date(dstEdate)), serverTimezone), "yyyy-MM-dd'T'HH:mm:ssXXX" ); const eformattedDateWithOffset = format( zonedTimeToUtc(endOfDay(new Date(dstEdate)), serverTimezone), "yyyy-MM-dd'T'HH:mm:ssXXX" );
当前输出
DST结束
埃及时区起始时间:2024-10-30T21:00:00.000Z
埃及时区结束时间:2024-10-31T21:59:59.000ZDST开始
埃及时区起始时间:2024-04-25T21:00:00.000Z
埃及时区结束时间:2024-04-26T20:59:59.000Z
期望输出
DST结束
埃及时区起始时间:2024-10-30T21:00:00.000Z
埃及时区结束时间:2024-10-31T21:59:59.000ZDST开始
埃及时区起始时间:2024-04-25T22:00:00.000Z(正确时间)
埃及时区结束时间:2024-04-26T20:59:59.000Z
问题分析与解决方法
问题根源在于startOfDay与zonedTimeToUtc的组合逻辑:当DST在凌晨12点生效时,startOfDay(new Date(dstSdate))生成的当地时间00:00,其对应的时区偏移已完成切换,但原有逻辑未正确识别该偏移变化,导致UTC转换错误。
调整代码逻辑,直接构造带具体时间的本地日期字符串,确保使用切换后的时区偏移计算UTC时间:
const dstSdate = '2024-04-26'; const serverTimezone = 'Africa/Cairo'; // 直接构造当地时间的起始、结束时刻 const localStart = new Date(`${dstSdate}T00:00:00`); const localEnd = new Date(`${dstSdate}T23:59:59`); // 转换为UTC并格式化 const sformattedDateWithOffset = format( zonedTimeToUtc(localStart, serverTimezone), "yyyy-MM-dd'T'HH:mm:ssXXX" ); const eformattedDateWithOffset = format( zonedTimeToUtc(localEnd, serverTimezone), "yyyy-MM-dd'T'HH:mm:ssXXX" );
也可通过反向转换验证结果正确性:
// 将期望的UTC时间转回当地时间,验证是否为目标时刻 const correctUtcStart = new Date('2024-04-25T22:00:00.000Z'); const verifiedLocalStart = utcToZonedTime(correctUtcStart, serverTimezone); console.log(format(verifiedLocalStart, 'yyyy-MM-dd HH:mm:ss')); // 应输出2024-04-26 00:00:00
内容的提问来源于stack exchange,提问作者shaily rajput
相关产品推荐
相关产品推荐

