fix: Outlook UTC date parsing and event deduplication

- Outlook returns dateTime without Z suffix despite timeZone being UTC,
  causing JS to parse as local time (1h shift). Now appends Z for UTC dates.
- Added frontend deduplication to prevent stacked rendering of duplicate events.
- Added Outlook event debug logging for recurring event investigation.

v1.62.3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
mARTin 2026-03-24 00:22:56 +01:00
parent c302a036bb
commit 8abbf4a286
4 changed files with 17 additions and 5 deletions

View File

@ -1,6 +1,6 @@
{
"name": "my-weekly-todo-list",
"version": "1.62.2",
"version": "1.62.3",
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
"main": "index.js",
"scripts": {

View File

@ -1607,9 +1607,14 @@ export default function WeeklyView() {
type WeatherHour = { temp: number; code: number; feelsLike?: number; wind?: number; gusts?: number; precipProb?: number; precip?: number; humidity?: number; uv?: number };
const [weatherData, setWeatherData] = useState<Record<string, WeatherHour>>({});
// Extend events with editable flag from connections
// Extend events with editable flag from connections, deduplicate by id
const calendarEvents = useMemo(() => {
return rawCalendarEvents.map((event) => {
const seen = new Set<string>();
return rawCalendarEvents.filter((event) => {
if (seen.has(event.id)) return false;
seen.add(event.id);
return true;
}).map((event) => {
let isEditable = false;
if (event.calendarId) {
for (const conn of connections) {

View File

@ -620,6 +620,8 @@ export const getCalendarEvents = async (
const calendarData = calendars.find(c => c.id === calendarId);
console.log(`[CALENDAR] Outlook calendar ${calendarId}: ${outlookEvents.length} events`, outlookEvents.map((e: any) => ({ id: e.id?.slice(-10), title: e.summary, start: e.start?.dateTime?.slice(0, 16), recurring: e.isRecurring })));
events = events.concat(outlookEvents.map((event: any) => ({
id: event.id,
title: event.summary || '(No Title)',

View File

@ -212,16 +212,21 @@ export const getUpcomingEvents = async (
'normal': 'default', 'personal': 'default', 'private': 'private', 'confidential': 'confidential',
};
// Outlook returns dateTime without Z suffix even when timeZone is UTC.
// Append Z so JS Date parsing treats it as UTC (not local time).
const fixUtc = (dt: string, tz: string) =>
dt && tz === 'UTC' && !dt.endsWith('Z') ? dt + 'Z' : dt;
return {
id: event.seriesMasterId ? `${event.seriesMasterId}::${event.id}` : event.id,
summary: event.subject,
description: event.body?.content || event.bodyPreview,
start: {
dateTime: event.start.dateTime,
dateTime: fixUtc(event.start.dateTime, event.start.timeZone),
timeZone: event.start.timeZone
},
end: {
dateTime: event.end.dateTime,
dateTime: fixUtc(event.end.dateTime, event.end.timeZone),
timeZone: event.end.timeZone
},
location: event.location?.displayName,