检测给定时间是否处于查塔姆群岛时区DST空时段问题排查
解决查塔姆群岛夏令时空时段的检测问题
我明白你的痛点了——查塔姆群岛这个时区的夏令时切换确实很特殊,2018年9月30日02:45到03:45是个完全不存在的“空窗口”,你希望用户选这个时段的时间时收到提醒,但现有代码没做到,咱们来一步步解决这个问题。
先说说现有代码的问题
你之前用的stdTimezoneOffset方法是拿1月和7月的时区偏移来判断夏令时,但这种方法只能知道当前是否处于夏令时,没法检测那个特定的1小时空窗口。因为查塔姆群岛的DST切换不是在常规的冬夏月份,而且当你输入这个空窗口的时间时,JavaScript会自动把它调整到实际存在的时间(比如输入02:50,JS会偷偷改成03:50),所以常规的夏令时检测根本发现不了这个异常。
针对性的解决方案
我们需要直接检测用户输入的时间是否落在2018年9月30日02:45-03:45这个不存在的窗口里,核心思路是:
- 先判断日期是否是2018年9月30日
- 再判断时间是否在02:45到03:45之间
- 最后验证JavaScript是否自动调整了这个时间(因为不存在的时间会被JS修正)
下面是具体的代码实现:
function isInChathamDSTGap(date) { // 锁定目标日期:2018年9月30日(注意JS月份是0基,9月对应8) const targetYear = 2018; const targetMonth = 8; const targetDay = 30; // 获取输入时间的本地时间组件 const localYear = date.getFullYear(); const localMonth = date.getMonth(); const localDay = date.getDate(); const localHours = date.getHours(); const localMinutes = date.getMinutes(); // 第一步:先确认是不是目标日期 if (localYear !== targetYear || localMonth !== targetMonth || localDay !== targetDay) { return false; } // 第二步:检查时间是否落在02:45到03:45之间 const isInTimeRange = (localHours === 2 && localMinutes >= 45) || (localHours === 3 && localMinutes < 45); if (!isInTimeRange) { return false; } // 第三步:验证JS是否自动调整了这个时间 // 用同样的本地时间组件重新构造Date,看是否和原时间不一致 const adjustedDate = new Date(localYear, localMonth, localDay, localHours, localMinutes); return adjustedDate.getHours() !== localHours || adjustedDate.getMinutes() !== localMinutes; } // 测试用例 const invalidTime = new Date(2018, 8, 30, 2, 50); // 输入不存在的02:50 console.log(isInChathamDSTGap(invalidTime)); // 输出true,应该触发通知 const validTime1 = new Date(2018, 8, 30, 2, 40); // 切换前的有效时间 console.log(isInChathamDSTGap(validTime1)); // 输出false const validTime2 = new Date(2018, 8, 30, 3, 50); // 切换后的有效时间 console.log(isInChathamDSTGap(validTime2)); // 输出false
代码逻辑解释
- 首先锁定目标日期,避免对其他日期做无效检测
- 然后筛选出时间在02:45-03:45的范围
- 最后通过重新构造Date对象,验证JS是否自动修正了时间——因为不存在的时间会被JS加上1小时(比如02:50变成03:50),所以调整后的时间和原输入的时间组件会不一致,这就说明用户输入的是那个空窗口里的时间。
这样你就可以在用户选择时间后,调用这个函数,如果返回true,就弹出通知提示用户这个时间不存在啦。
内容的提问来源于stack exchange,提问作者marimuthu selvaraj
相关产品推荐
相关产品推荐

