From 3302a075af5fc8455a4c6cd97be8dc45a499208f Mon Sep 17 00:00:00 2001 From: Alexander Huck Date: Tue, 10 Sep 2024 20:57:23 +0200 Subject: [PATCH 1/2] fix: retrieve events in UTC --- internal/adapter/google/client.go | 1 + internal/adapter/outlook_http/client.go | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/internal/adapter/google/client.go b/internal/adapter/google/client.go index 80f5097..25c0034 100644 --- a/internal/adapter/google/client.go +++ b/internal/adapter/google/client.go @@ -58,6 +58,7 @@ func (g *GCalClient) ListEvents(ctx context.Context, starttime time.Time, endtim TimeMin(starttime.Format(time.RFC3339)). TimeMax(endtime.Format(time.RFC3339)). MaxResults(defaultPageMaxResults). + TimeZone("UTC"). OrderBy("startTime"). Context(ctx) diff --git a/internal/adapter/outlook_http/client.go b/internal/adapter/outlook_http/client.go index 5aa7fcb..60bd51b 100644 --- a/internal/adapter/outlook_http/client.go +++ b/internal/adapter/outlook_http/client.go @@ -36,7 +36,16 @@ func (o *OutlookClient) ListEvents(ctx context.Context, start time.Time, end tim // Otherwise this always ends in a 500 return code, see also https://stackoverflow.com/a/62770941 query := "?startDateTime=" + startDate + "&endDateTime=" + endDate + "&$expand=extensions($filter=Id%20eq%20'inovex.calendarsync.meta')" - resp, err := o.Client.Get(baseUrl + "/me/calendars/" + o.CalendarID + "/CalendarView" + query) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, baseUrl+"/me/calendars/"+o.CalendarID+"/CalendarView"+query, nil) + if err != nil { + return nil, err + } + + // Get all the events in UTC timezone + // when we retrieve them from other adapters they will also be in UTC + req.Header.Add("Prefer", "outlook.timezone=\"UTC\"") + + resp, err := o.Client.Do(req) if err != nil { return nil, err } From 5f6ae85f9f86fc3ba74e285ecbcae9857243171f Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Thu, 10 Oct 2024 19:49:48 +0200 Subject: [PATCH 2/2] outlook: correctly create events using UTC timezone When creating an event, the timestamp's timezone was silently dropped and replaced with the timezone of the local system. Timestamps returned by outlook are in UTC, such that syncing from outlook to outlook resulted in shifted events on non-UTC systems. Explicitly convert timestamps to UTC to ensure correctness. --- go.mod | 1 - go.sum | 3 --- internal/adapter/outlook_http/client.go | 15 ++++----------- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 06d0c41..e6a9856 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,6 @@ require ( github.com/microcosm-cc/bluemonday v1.0.27 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/stretchr/testify v1.9.0 - github.com/thlib/go-timezone-local v0.0.3 github.com/urfave/cli/v2 v2.27.4 go.uber.org/ratelimit v0.3.1 golang.org/x/oauth2 v0.23.0 diff --git a/go.sum b/go.sum index e2edc05..c562058 100644 --- a/go.sum +++ b/go.sum @@ -120,8 +120,6 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/teambition/rrule-go v1.7.2/go.mod h1:mBJ1Ht5uboJ6jexKdNUJg2NcwP8uUMNvStWXlJD3MvU= github.com/teambition/rrule-go v1.8.2 h1:lIjpjvWTj9fFUZCmuoVDrKVOtdiyzbzc93qTmRVe/J8= github.com/teambition/rrule-go v1.8.2/go.mod h1:Ieq5AbrKGciP1V//Wq8ktsTXwSwJHDD5mD/wLBGl3p4= -github.com/thlib/go-timezone-local v0.0.3 h1:ie5XtZWG5lQ4+1MtC5KZ/FeWlOKzW2nPoUnXYUbV/1s= -github.com/thlib/go-timezone-local v0.0.3/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI= github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= @@ -171,7 +169,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/internal/adapter/outlook_http/client.go b/internal/adapter/outlook_http/client.go index 60bd51b..589b04c 100644 --- a/internal/adapter/outlook_http/client.go +++ b/internal/adapter/outlook_http/client.go @@ -12,7 +12,6 @@ import ( "time" "github.com/charmbracelet/log" - "github.com/thlib/go-timezone-local/tzlocal" "github.com/inovex/CalendarSync/internal/models" ) @@ -190,16 +189,10 @@ func (o OutlookClient) eventToOutlookEvent(e models.Event) (oe Event) { outlookEvent := Event{} outlookEvent.Location.Name = e.Location - // microsoft expects iana time zone codes, but the go standard library returns abbreviations like "CET" - // NOTE: This may not work when events get imported from other time zones, i would expect golang to properly format the time strings correctly using the local runtime timezone - tzname, err := tzlocal.RuntimeTZ() - if err != nil { - tzname = "UTC" - } - outlookEvent.Start.DateTime = e.StartTime.Format(timeFormat) - outlookEvent.Start.TimeZone = tzname - outlookEvent.End.DateTime = e.EndTime.Format(timeFormat) - outlookEvent.End.TimeZone = tzname + outlookEvent.Start.DateTime = e.StartTime.UTC().Format(timeFormat) + outlookEvent.Start.TimeZone = "UTC" + outlookEvent.End.DateTime = e.EndTime.UTC().Format(timeFormat) + outlookEvent.End.TimeZone = "UTC" outlookEvent.Subject = e.Title outlookEvent.ID = e.ID