Angular Calendar夏令时时区下周视图时间显示异常求助
Angular Calendar周视图夏令时时区重复时间问题修复方案
问题背景
使用angular-calendar周视图并配置[hourSegmentTemplate]后,在开启自动夏令时的时区(如UTC+01:00布鲁塞尔/哥本哈根/马德里/巴黎)下,时间轴出现重复小时(如连续两个3am),同时事件回调返回的时间值也存在错误,官方示例也可复现该问题。
修复方案
1. 统一时区处理逻辑
强制使用UTC或指定时区处理日期,规避夏令时切换带来的时间歧义:
- 初始化
viewDate时使用UTC时间:this.viewDate = new Date(Date.UTC( new Date().getUTCFullYear(), new Date().getUTCMonth(), new Date().getUTCDate() )); - 处理
eventTimesChanged回调时,手动校正时区偏移:handleEditEvent(event: { event: CalendarEvent, newStart: Date, newEnd: Date }) { // 以欧洲中部时区为例,夏令时偏移为120分钟,非夏令时为60分钟 const isDST = this.isInDST(event.newStart); const timezoneOffset = isDST ? 120 : 60; const correctedStart = new Date(event.newStart.getTime() + timezoneOffset * 60 * 1000); const correctedEnd = new Date(event.newEnd.getTime() + timezoneOffset * 60 * 1000); event.event.start = correctedStart; event.event.end = correctedEnd; }
2. 自定义小时段时间格式化
修改hourSegmentTemplate,通过自定义方法计算并显示正确时间,绕过库内置的时区bug:
- 模板代码:
<ng-template #weekViewHourSegmentTemplate let-segment="segment"> <div class="cal-hour-segment"> <span class="cal-time">{{ formatSegmentTime(segment.date) }}</span> </div> </ng-template> - 组件中实现格式化方法(适配欧洲中部夏令时规则):
formatSegmentTime(date: Date): string { let hour = date.getHours(); // 处理夏令时结束当天的重复小时(10月最后一个周日的2-3am时段) if (this.isDstTransitionHour(date)) { hour -= 1; } // 转换为12小时制格式 const period = hour >= 12 ? 'pm' : 'am'; const displayHour = hour % 12 === 0 ? 12 : hour % 12; return `${displayHour} ${period}`; } // 判断是否处于欧洲中部夏令时区间 isInDST(date: Date): boolean { const year = date.getFullYear(); const dstStart = this.getLastSunday(year, 2); // 3月最后一个周日 dstStart.setHours(2, 0, 0); const dstEnd = this.getLastSunday(year, 9); // 10月最后一个周日 dstEnd.setHours(3, 0, 0); return date >= dstStart && date < dstEnd; } // 判断是否是夏令时结束时的重复小时段 isDstTransitionHour(date: Date): boolean { const dstEnd = this.getLastSunday(date.getFullYear(), 9); dstEnd.setHours(2, 0, 0); const transitionEnd = new Date(dstEnd.getTime() + 3600000); return date >= dstEnd && date < transitionEnd; } // 获取指定年月的最后一个周日 getLastSunday(year: number, month: number): Date { const lastDay = new Date(year, month + 1, 0); const dayDiff = lastDay.getDay() === 0 ? 0 : lastDay.getDay(); return new Date(year, month, lastDay.getDate() - dayDiff); }
3. 升级组件版本
检查angular-calendar是否有最新版本修复了该时区问题,执行升级命令:
npm install angular-calendar@latest --save
4. 临时应急方案
若上述方案暂无法实施,可临时关闭系统的「自动夏令时调整」选项,避免时间重复问题,但此为临时措施,不推荐长期使用。
内容的提问来源于stack exchange,提问作者Towhidul Islam
相关产品推荐
相关产品推荐

