FullCalendar切换非UTC/local时区时事件日期不更新问题
问题
使用FullCalendar时,通过下拉选择器切换时区,选择UTC或local时区功能正常,但切换到其他时区时,日历上的事件日期并未更新。控制台可看到时区已更改,但事件无法正确显示对应时区的日期。
错误原因
时区切换时手动修改事件的start/end时间是多余操作,FullCalendar会根据设置的timeZone自动转换事件显示时间,无需手动调整。此外,手动转换时使用了错误的日期格式(DD-MM-YYYYTh:mm:ssZ),FullCalendar无法正确解析该格式,导致事件显示异常。
修复后的完整代码
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@5.3.1/main.min.css' rel='stylesheet' /> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" > <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="https://unpkg.com/popper.js/dist/umd/popper.min.js"></script> <script src="https://unpkg.com/tooltip.js/dist/umd/tooltip.min.js"></script> <script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.3.1/main.min.js'></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.min.js"></script> <script src="https://momentjs.com/downloads/moment-timezone-with-data.min.js"></script> <div class="container"> <div class="row"> <div class="col-md-12 mt-5 mb-5"> <label>Timezone:</label> <select id='time-zone-selector' class="form-control"> <option value='local'>local</option> <option value='UTC' selected>UTC</option> </select> <div style='float:right'> <span id='loading'>loading...</span> </div> <div id='calendar' class="mt-3"></div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { var initialTimeZone = 'UTC'; var timeZoneSelectorEl = document.getElementById('time-zone-selector'); var loadingEl = document.getElementById('loading'); var calendarEl = document.getElementById('calendar'); var calendar = new FullCalendar.Calendar(calendarEl, { timeZone: initialTimeZone, headerToolbar: { left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' }, navLinks: true, // can click day/week names to navigate views editable: true, selectable: true, dayMaxEvents: true, // allow "more" link when too many events eventDidMount: function(info) { var tooltip = new Tooltip(info.el, { title: info.event.extendedProps.days, placement: 'top', trigger: 'hover', container: 'body' }); }, events: [ {"title":"ThetaHealing Manifesting","url":"http:\/\/wordpress.local\/product\/thetahealing","start":"2023-03-03T07:00:00Z","end":"2023-03-04T14:00:00Z","extraParams":{"days":"2 Days Classes ","date":"Time (UTC): 07:00 am to 02:00 pm"}}, {"title":"ThetaHealing","url":"http:\/\/wordpress.local\/product\/thetahealing-you","start":"2023-02-13T02:00:00Z","end":"2023-02-14T09:00:00Z","extraParams":{"days":"2 Days Classes ","date":"Time (UTC): 02:00 am to 09:00 am"}}, {"title":"ThetaHealinge","url":"http:\/\/wordpress.local\/product\/thetahealing-you","start":"2023-03-23T17:00:00Z","end":"2023-03-24T23:59:00","extraParams":{"days":"2 Days Classes ","date":"Time (UTC): 05:00 pm to 11:59 pm"}} ], loading: function(bool) { loadingEl.style.display = bool ? 'inline' : 'none'; }, eventTimeFormat: { hour: 'numeric', minute: '2-digit', timeZoneName: 'short' } }); calendar.render(); calendar.on('dateClick', function(info) { console.log('clicked on ' + info.dateStr); }); FullCalendar.requestJson('GET', 'https://fullcalendar.io/demo-timezones.json', {}, function(timeZones) { timeZones.forEach(function(timeZone) { if (timeZone !== 'UTC') { // UTC is already in the list var optionEl = document.createElement('option'); optionEl.value = timeZone; optionEl.innerText = timeZone; timeZoneSelectorEl.appendChild(optionEl); } }); }); timeZoneSelectorEl.addEventListener('change', function() { var newTimeZone = this.value; // 直接更新时区,FullCalendar自动处理事件转换 calendar.setOption('timeZone', newTimeZone); calendar.render(); }); }); </script>
关键修复点
- 删除了手动转换事件
start/end时间的逻辑,FullCalendar会根据设置的timeZone自动完成时区转换 - 确保事件原始时间为带UTC标识的标准ISO格式(如
2023-03-03T07:00:00Z),这是FullCalendar正确解析和转换时区的前提
内容的提问来源于stack exchange,提问作者WeDevelop
相关产品推荐
相关产品推荐

