Incorrect Timezone Handling in CalDAV Event Creation #99

Open
opened 2026-02-28 01:28:23 -05:00 by deekerman · 4 comments
Owner

Originally created by @Passthem-desu on GitHub (Jun 18, 2025).

Description:

I'm experiencing an issue with Fluid Calendar where events created within the application are displayed incorrectly in other calendar applications like Thunderbird and Home Assistant. Specifically, these events are shifted by 8 hours. Events created in other applications, however, display correctly in Fluid Calendar.

I'm currently using the application in the Asia/Shanghai (UTC+8) timezone.

I've investigated the generated CalDAV files to understand the discrepancy. Here's a VEVENT created in Fluid Calendar that exhibits the incorrect behavior:

BEGIN:VEVENT
UID:bb06xxxx-xxxx-xxxx-xxxx-xxxxxxxx24e3
DTSTART:20250619T093000
DTEND:20250619T113000
DTSTAMP:20250618T192226Z
RRULE:FREQ=DAILY
SUMMARY:XXXXXX
END:VEVENT

In Fluid Calendar's web interface, this event correctly displays from 17:30 to 19:30 (Asia/Shanghai timezone). However, in other applications, it incorrectly shows as 9:30 to 11:30.

For comparison, here's an example of a correctly behaving event (created in Thunderbird) that displays accurately in both Fluid Calendar and Thunderbird:

BEGIN:VEVENT
UID:7ac3xxxx-xxxx-xxxx-xxxx-xxxxxxxx0fda
DTSTART;TZID=Asia/Shanghai:20250618T223000
DTEND;TZID=Asia/Shanghai:20250618T224500
CREATED:20250618T133402Z
DTSTAMP:20250618T143551Z
LAST-MODIFIED:20250618T143551Z
SUMMARY:XXXXXX
TRANSP:OPAQUE
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:默认 Mozilla 描述
TRIGGER:PT0S
END:VALARM
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:默认 Mozilla 描述
TRIGGER:PT5M
END:VALARM
X-MOZ-GENERATION:3
X-MOZ-LASTACK:20250618T143551Z
END:VEVENT

Crucially, the DTSTART and DTEND properties in the correct event are explicitly marked with TZID=Asia/Shanghai. This suggests a potential issue with how Fluid Calendar handles timezones during event creation.

Possible Solution:

The DTSTART value "20250619T093000" in the problematic event lacks a "Z" suffix. According to the W3C specification on Floating Time this indicates that the time is to be interpreted as "floating" or "local time." This means it could be 17:30 in UTC+8 (Asia/Shanghai) or 9:30 in UTC (which might be the server's timezone), explaining why it's handled correctly in the web UI.

However, other calendar applications may not interpret this "floating time" correctly when their local timezone differs from the server's, leading to the observed 8-hour shift.

Therefore, a robust solution would be to explicitly mark event times with the local timezone using the TZID property. This would ensure clarity and consistent interpretation of event times across all applications, regardless of their local timezone settings.

Originally created by @Passthem-desu on GitHub (Jun 18, 2025). ## Description: I'm experiencing an issue with Fluid Calendar where events created within the application are displayed incorrectly in other calendar applications like Thunderbird and Home Assistant. Specifically, these events are shifted by 8 hours. Events created in other applications, however, display correctly in Fluid Calendar. I'm currently using the application in the **Asia/Shanghai** (UTC+8) timezone. I've investigated the generated CalDAV files to understand the discrepancy. Here's a VEVENT created in Fluid Calendar that exhibits the incorrect behavior: ``` BEGIN:VEVENT UID:bb06xxxx-xxxx-xxxx-xxxx-xxxxxxxx24e3 DTSTART:20250619T093000 DTEND:20250619T113000 DTSTAMP:20250618T192226Z RRULE:FREQ=DAILY SUMMARY:XXXXXX END:VEVENT ``` In Fluid Calendar's web interface, this event correctly displays from **17:30** to **19:30** (Asia/Shanghai timezone). However, in other applications, it incorrectly shows as **9:30** to **11:30**. For comparison, here's an example of a correctly behaving event (created in Thunderbird) that displays accurately in both Fluid Calendar and Thunderbird: ``` BEGIN:VEVENT UID:7ac3xxxx-xxxx-xxxx-xxxx-xxxxxxxx0fda DTSTART;TZID=Asia/Shanghai:20250618T223000 DTEND;TZID=Asia/Shanghai:20250618T224500 CREATED:20250618T133402Z DTSTAMP:20250618T143551Z LAST-MODIFIED:20250618T143551Z SUMMARY:XXXXXX TRANSP:OPAQUE BEGIN:VALARM ACTION:DISPLAY DESCRIPTION:默认 Mozilla 描述 TRIGGER:PT0S END:VALARM BEGIN:VALARM ACTION:DISPLAY DESCRIPTION:默认 Mozilla 描述 TRIGGER:PT5M END:VALARM X-MOZ-GENERATION:3 X-MOZ-LASTACK:20250618T143551Z END:VEVENT ``` Crucially, the `DTSTART` and `DTEND` properties in the correct event are explicitly marked with `TZID=Asia/Shanghai`. This suggests a potential issue with how Fluid Calendar handles timezones during event creation. ## Possible Solution: The `DTSTART` value "20250619T093000" in the problematic event lacks a "Z" suffix. According to the [W3C specification on Floating Time](https://www.w3.org/International/wiki/FloatingTime) this indicates that the time is to be interpreted as "floating" or "local time." This means it could be **17:30 in UTC+8** (Asia/Shanghai) or **9:30 in UTC** (which might be the server's timezone), explaining why it's handled correctly in the web UI. However, other calendar applications may not interpret this "floating time" correctly when their local timezone differs from the server's, leading to the observed 8-hour shift. Therefore, a robust solution would be to explicitly mark event times with the local timezone using the `TZID` property. This would ensure clarity and consistent interpretation of event times across all applications, regardless of their local timezone settings.
Author
Owner

@Passthem-desu commented on GitHub (Jun 18, 2025):

Oh, here's a workaround by adding "TZ=Asia/Shanghai" into the environment file. However, the issue still affects those who want to collaborate in different timezones...

@Passthem-desu commented on GitHub (Jun 18, 2025): Oh, here's a workaround by adding "TZ=Asia/Shanghai" into the environment file. However, the issue still affects those who want to collaborate in different timezones...
Author
Owner

@shuperluu commented on GitHub (Jun 27, 2025):

Could this be the reason why I cannot create All day events but can create events that goes from 00:00 to 24:00?

@shuperluu commented on GitHub (Jun 27, 2025): Could this be the reason why I cannot create All day events but can create events that goes from 00:00 to 24:00?
Author
Owner

@cboy60 commented on GitHub (Sep 10, 2025):

I was having a similar issue — my event times were off by 4 hours, which I believe shares the same root cause described here.

I tried setting TZ=America/New_York both in my .env file and explicitly under the environment section of my docker-compose.yaml, but the issue persisted. To debug, I ran:

docker exec -it date

This returned a UTC time, whereas I expected EDT, given the TZ setting. That suggested the container wasn't respecting the timezone config.

The workaround I found was to create a custom Dockerfile that installs tzdata explicitly:

FROM eibrahim/fluid-calendar:latest

USER root
RUN apk add --no-cache tzdata
ENV TZ=America/New_York
USER nextjs

Then I built the image locally:

docker build -t my-fluid-calendar-custom .

And updated my Compose file to use this local image. After doing that, the time inside the container reflected the correct timezone, and events created in FluidCalendar now show the correct time in third-party CalDAV clients.

Not an ideal long-term fix, since it requires rebuilding the image for any upstream updates, but it's working for now. Hopefully this helps others hitting the same issue.

@cboy60 commented on GitHub (Sep 10, 2025): I was having a similar issue — my event times were off by 4 hours, which I believe shares the same root cause described here. I tried setting TZ=America/New_York both in my .env file and explicitly under the environment section of my docker-compose.yaml, but the issue persisted. To debug, I ran: docker exec -it <container name> date This returned a UTC time, whereas I expected EDT, given the TZ setting. That suggested the container wasn't respecting the timezone config. The workaround I found was to create a custom Dockerfile that installs tzdata explicitly: FROM eibrahim/fluid-calendar:latest USER root RUN apk add --no-cache tzdata ENV TZ=America/New_York USER nextjs Then I built the image locally: docker build -t my-fluid-calendar-custom . And updated my Compose file to use this local image. After doing that, the time inside the container reflected the correct timezone, and events created in FluidCalendar now show the correct time in third-party CalDAV clients. Not an ideal long-term fix, since it requires rebuilding the image for any upstream updates, but it's working for now. Hopefully this helps others hitting the same issue.
Author
Owner

@shuperluu commented on GitHub (Sep 17, 2025):

I don't have enough knowledge to manipulate thigs like that or try to submit a PR.

@eibrahim Any chance you look into this for a next release?

@shuperluu commented on GitHub (Sep 17, 2025): I don't have enough knowledge to manipulate thigs like that or try to submit a PR. @eibrahim Any chance you look into this for a next release?
Sign in to join this conversation.
No labels
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/fluid-calendar#99
No description provided.