Open aukfood opened 3 weeks ago
Bonjour @aukfood! I'm here to help you with any bugs, questions, or contributions you have regarding the repository. Let's work together to resolve the issue you're experiencing.
To resolve the two-hour time discrepancy in Nextcloud Agenda when creating events using cal.com integrated with the Nextcloud agenda, you need to ensure that the time zones are correctly set and synchronized between the two systems. Here are the key points to check and adjust:
Ensure Time Zone Consistency: Make sure that the time zone settings in both Nextcloud and cal.com are consistent. The setNewTimeZone
function in cal.com updates the user's time zone and their default schedule's time zone.
Update Time Zones: Ensure that the travel schedules are correctly set and that the time zone changes are applied as expected.
Check for Time Zone Offsets: The code calculates the UTC offset for the user's time zone and adjusts the start and end dates of travel schedules accordingly. Ensure that these calculations are correct and that the time zone offsets are properly applied.
Additionally, the buildSlots
function in packages/lib/slots.ts
handles the creation of time slots and takes into account the time zone differences between the organizer and the invitee. It calculates the differences in UTC offsets due to Daylight Saving Time (DST) and adjusts the slot times accordingly.
Here is the relevant part of the code that updates the time zone:
const setNewTimeZone = async (timeZone: string, user: { id: number; defaultScheduleId: number | null }) => {
await prisma.user.update({
where: {
id: user.id,
},
data: {
timeZone: timeZone,
},
});
const defaultScheduleId = await getDefaultScheduleId(user.id, prisma);
if (!user.defaultScheduleId) {
// set default schedule if not already set
await prisma.user.update({
where: {
id: user.id,
},
data: {
defaultScheduleId,
},
});
}
await prisma.schedule.updateMany({
where: {
id: defaultScheduleId,
},
data: {
timeZone: timeZone,
},
});
timeZonesChanged++;
};
And here is the relevant part of the buildSlots
function that handles time zone differences:
const organizerDSTDiff =
dayjs().tz(organizerTimeZone).utcOffset() - startOfInviteeDay.tz(organizerTimeZone).utcOffset();
const inviteeDSTDiff =
dayjs().tz(inviteeTimeZone).utcOffset() - startOfInviteeDay.tz(inviteeTimeZone).utcOffset();
const slots: { time: Dayjs; userIds?: number[] }[] = [];
const getTime = (time: number) => {
const minutes = time + organizerDSTDiff - inviteeDSTDiff;
return startOfInviteeDay.tz(inviteeTimeZone).add(minutes, "minutes");
};
Additionally, the useTimezone
hook in useTimezone.ts
ensures that the user's preferred time zone is used and updated correctly:
import { useEffect } from "react";
import dayjs from "@calcom/dayjs";
import { useMe } from "./useMe";
export const useTimezone = (
onTimeZoneChange?: (currentTimezone: string) => void,
currentTimezone: string = dayjs.tz.guess()
) => {
const { data: me, isLoading } = useMe();
const preferredTimezone = me?.data?.timeZone ?? currentTimezone;
useEffect(() => {
if (!isLoading && preferredTimezone && onTimeZoneChange && preferredTimezone !== currentTimezone) {
onTimeZoneChange(currentTimezone);
}
}, [currentTimezone, preferredTimezone, onTimeZoneChange, isLoading]);
};
To resolve the discrepancy, ensure that:
Additionally, ensure that the dayjs
library used in cal.com is correctly patched to handle time zones accurately. The patch provided in .yarn/patches/dayjs-npm-1.11.2-644b12fe04.patch
includes updates to the timezone.js
plugin to improve time zone handling:
diff --git a/plugin/timezone.js b/plugin/timezone.js
index fb6112a96f03f53ba78162ac323dce17f635161d..991e4e5410a32f5a69cb6e0e9476a9c529657aae 100644
--- a/plugin/timezone.js
+++ b/plugin/timezone.js
@@ -1 +1 @@
-!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).dayjs_plugin_timezone=e()}(this,(function(){"use strict";var t={year:0,month:1,day:2,hour:3,minute:4,second:5},e={};return function(n,i,o){var r,a=function(t,n,i){void 0===i&&(i={});var o=new Date(t),r=function(t,n){void 0===n&&(n={});var i=n.timeZoneName||"short",o=t+"|"+i,r=e[o];return r||(r=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:i}),e[o]=r),r}(n,i);return r.formatToParts(o)},u=function(e,n){for(var i=a(e,n),r=[],u=0;u<i.length;u+=1){var f=i[u],s=f.type,m=f.value,c=t[s];c>=0&&(r[c]=parseInt(m,10))}var d=r[3],l=24===d?0:d,v=r[0]+"-"+r[1]+"-"+r[2]+" "+l+":"+r[4]+":"+r[5]+":000",h=+e;return(o.utc(v).valueOf()-(h-=h%1e3))/6e4},f=i.prototype;f.tz=function(t,e){void 0===t&&(t=r);var n=this.utcOffset(),i=this.toDate(),a=i.toLocaleString("en-US",{timeZone:t}),u=Math.round((i-new Date(a))/1e3/60),f=o(a).$set("millisecond",this.$ms).utcOffset(15*-Math.round(i.getTimezoneOffset()/15)-u,!0);if(e){var s=f.utcOffset();f=f.add(n-s,"minute")}return f.$x.$timezone=t,f},f.offsetName=function(t){var e=this.$x.$timezone||o.tz.guess(),n=a(this.valueOf(),e,{timeZoneName:t}).find((function(t){return"timezonename"===t.type.toLowerCase()}));return n&&n.value};var s=f.startOf;f.startOf=function(t,e){if(!this.$x||!this.$x.$timezone)return s.call(this,t,e);var n=o(this.format("YYYY-MM-DD HH:mm:ss:SSS"));return s.call(n,t,e).tz(this.$x.$timezone,!0)},o.tz=function(t,e,n){var i=n&&e,a=n||e||r,f=u(+o(),a);if("string"!=typeof t)return o(t).tz(a);var s=function(t,e,n){var i=t-60*e*1e3,o=u(i,n);if(e===o)return[i,e];var r=u(i-=60*(o-e)*1e3,n);return o===r?[i,o]:[t-60*Math.min(o,r)*1e3,Math.max(o,r)]}(o.utc(t,i).valueOf(),f,a),m=s[0],c=s[1],d=o(m).utcOffset(c);return d.$x.$timezone=a,d},o.tz.guess=function(){return
Intl.DateTimeFormat().resolvedOptions().timeZone},o.tz.setDefault=function(t){r=t}}}));
\ No newline at end of file
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).dayjs_plugin_timezone=e()}(this,(function(){"use strict";function t(){return t=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t},t.apply(this,arguments)}var e={year:0,month:1,day:2,hour:3,minute:4,second:5},n={year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"},i={},r={};return function(o,a,u){var f,s=function(e,r,o){void 0===o&&(o={});var a=new Date(e),u=function(e,r){void 0===r&&(r={});var o=r.timeZoneName||"short",a=e+"|"+o,u=i[a];return u||(u=new Intl.DateTimeFormat("en-US",t({},n,{hour12:!1,timeZone:e,timeZoneName:o})),i[a]=u),u}(r,o);return u.formatToParts(a)},m=function(t,n){for(var i=s(t,n),r=[],o=0;o<i.length;o+=1){var a=i[o],f=a.type,m=a.value,c=e[f];c>=0&&(r[c]=parseInt(m,10))}var l=r[3],d=24===l?0:l,h=r[0]+"-"+r[1]+"-"+r[2]+" "+d+":"+r[4]+":"+r[5]+":000",v=+t;return(u.utc(h).valueOf()-(v-=v%1e3))/6e4},c=a.prototype;c.tz=function(e,i){void 0===e&&(e=f);var o=this.utcOffset(),a=this.toDate(),s=function(e){var i=r[e];return i||(i=new Intl.DateTimeFormat("en-US",t({},n,{timeZone:e})),r[e]=i),i}(e).format(a),m=Math.round((a-new Date(s))/1e3/60),c=u(s,{locale:this.$L}).$set("millisecond",this.$ms).utcOffset(15*-Math.round(a.getTimezoneOffset()/15)-m,!0);if(i){var l=c.utcOffset();c=c.add(o-l,"minute")}return c.$x.$timezone=e,c},c.offsetName=function(t){var e=this.$x.$timezone||u.tz.guess(),n=s(this.valueOf(),e,{timeZoneName:t}).find((function(t){return"timezonename"===t.type.toLowerCase()}));return n&&n.value};var l=c.startOf;c.startOf=function(t,e){if(!this.$x||!this.$x.$timezone)return l.call(this,t,e);var n=u(this.format("YYYY-MM-DD HH:mm:ss:SSS"),{locale:this.$L});return l.call(n,t,e).tz(this.$x.$timezone,!0)},u.tz=function(t,e,n){var
i=n&&e,r=n||e||f,o=m(+u(),r);if("string"!=typeof t)return u(t).tz(r);var a=function(t,e,n){var i=t-60*e*1e3,r=m(i,n);if(e===r)return[i,e];var o=m(i-=60*(r-e)*1e3,n);return r===o?[i,r]:[t-60*Math.min(r,o)*1e3,Math.max(r,o)]}(u.utc(t,i).valueOf(),o,r),s=a[0],c=a[1],l=u(s).utcOffset(c);return l.$x.$timezone=r,l},u.tz.guess=function(){return Intl.DateTimeFormat().resolvedOptions().timeZone},u.tz.setDefault=function(t){f=t}}}));
If the discrepancy persists, you may need to debug the time zone settings and offsets in both systems to identify any inconsistencies [1][2][3][4].
To continue talking to Dosu, mention @dosu.
What I see is that information in Nextcloud database is not registred with the good hour. For example I create an event for 20240614 at 10h30 am and in Nextcloud database is registred at DTSTART:20240614T083000Z
So if I create an event in Netcloud at 20240613 at 13h30 event is like that in database : DTSTART;TZID=Europe/Paris:20240613T133000
So I think that cal.com is not registred correctly time in nextcloud database. How to see timezone in cal.com container ?
Regards
Date in container is not good
b71d7c2b9a7f:/calcom# date
Wed Jun 12 16:27:48 2024
I try to add this in docker-compose
environment:
- DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB}
- TZ="Europe/Paris"
depends_on:
- database
volumes:
- "/etc/timezone:/etc/timezone:ro"
I set allo container with
volumes:
- "/etc/timezone:/etc/timezone:ro"
But same problem date is ok but creation in nextcloud is not goot
Found a bug? Please fill out the sections below. 👍
Issue Summary
When we create an event with cal.com integrated with Nextcloud agenda, we have two hours less time difference.
Steps to Reproduce
Any other relevant information. For example, why do you consider this a bug and what did you expect to happen instead?
Actual Results
In Nextcloud
In Thunderbird
Technical details
Thanks
CAL-3981