0

I need to create some events and upload them to a google calendar. Now I have hit an unforeseen bump, as the times and timezone offset gets changed automatically, once uploaded. I am working with a list of meetings, whose times should not be altered, indepedently of time zone or DST.

Since this topic has been touched upon here in stack overflow, I tried some of the solutions but they just created more confusing results.

Here are four events I created with different approaches:

  • Creating an event with time zone and offset
  • Creating an event with time zone but without offset
  • Creating an event without time zone, but with offset
  • Creating an event by uploading a CSV through the web interface

Creating an event with time zone and offset:

 static void dstUploadProbe(){
    //Initiate helper class to create OAuth2 token and get Calendar service
    CalendarHelper calendarHelper = new CalendarHelper();
    calendarHelper.initService();

    Event event = new Event();
    //event start time with time zone and offset
    DateTime startDateTime = new DateTime("2022-10-30T18:00:00+02:00");
    EventDateTime startEventDateTime = new EventDateTime();
    startEventDateTime.setDateTime(startDateTime);
    startEventDateTime.setTimeZone("Europe/Berlin");

    //end time
    DateTime endDateTime = new DateTime("2022-10-30T20:30:00+02:00");
    EventDateTime endEventDateTime = new EventDateTime();
    endEventDateTime.setDateTime(endDateTime);
    endEventDateTime.setTimeZone("Europe/Berlin");

    //create event
    event.setSummary("TestMeeting 1");
    event.setStart(startEventDateTime);
    event.setEnd(endEventDateTime);

    //upload event
    try {
        CalendarHelper.addEvent(calendarHelper.service,calendarHelper.currentCalendarId,event);
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
}

Creating an event with time zone WITHOUT offset

static void dstUploadProbe(){
    //Initiate helper class to create OAuth2 token and get Calendar service
    CalendarHelper calendarHelper = new CalendarHelper();
    calendarHelper.initService();

    Event event = new Event();
    //event start time with time zone WITHOUT offset
    DateTime startDateTime = new DateTime("2022-10-30T18:00:00");
    EventDateTime startEventDateTime = new EventDateTime();
    startEventDateTime.setDateTime(startDateTime);
    startEventDateTime.setTimeZone("Europe/Berlin");

    //end time
    DateTime endDateTime = new DateTime("2022-10-30T20:30:00");
    EventDateTime endEventDateTime = new EventDateTime();
    endEventDateTime.setDateTime(endDateTime);
    endEventDateTime.setTimeZone("Europe/Berlin");

    //create event
    event.setSummary("TestMeeting with tz but no offset");
    event.setStart(startEventDateTime);
    event.setEnd(endEventDateTime);

    //upload event
    try {
        CalendarHelper.addEvent(calendarHelper.service,calendarHelper.currentCalendarId,event);
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
}

Creating an event without time zone, but with offset

 static void dstUploadProbe(){
    //Initiate helper class to create OAuth2 token and get Calendar service
    CalendarHelper calendarHelper = new CalendarHelper();
    calendarHelper.initService();

    Event event = new Event();
    //event start time with time zone WITHOUT offset
    DateTime startDateTime = new DateTime("2022-10-30T18:00:00");
    EventDateTime startEventDateTime = new EventDateTime();
    startEventDateTime.setDateTime(startDateTime);

    //end time
    DateTime endDateTime = new DateTime("2022-10-30T20:30:00");
    EventDateTime endEventDateTime = new EventDateTime();
    endEventDateTime.setDateTime(endDateTime);

    //create event
    event.setSummary("TestMeeting with offset WITHOUT tz");
    event.setStart(startEventDateTime);
    event.setEnd(endEventDateTime);

    //upload event
    try {
        CalendarHelper.addEvent(calendarHelper.service,calendarHelper.currentCalendarId,event);
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
}

The uploaded CSV file contents:

Subject, Start Date, Start Time, End Time
Meeting uploaded in CSV,30/10/2022,06:00 PM, 08:30 PM

Here are the results as shown in the Calendar web view:

calendar web view

... and the resulting events, listed programatically.

Upcoming events

TestMeeting 1 (2022-10-30T17:00:00.000+01:00)

Meeting uploaded in CSV (2022-10-30T18:00:00.000+01:00)

TestMeeting with offset WITHOUT tz (2022-10-30T19:00:00.000+01:00)

TestMeeting with tz but no offset (2022-10-30T19:00:00.000+01:00)

Note how the time offsets have all been changed to +01:00 to compensate a change of DST. The only result that is as intended is the last one (CSV upload), but alas, that has not been reached using google api.

How can I navigate these waters without having to reinvent time?

3
  • 1
    Check what time zone is the calendar itself set to? By default this is the time zone that it displays, and it is effected by what time zone you are adding things as. Commented Oct 2, 2022 at 12:50
  • I forgot to mention: It works well for current events, eg. tomorrow or the day after. But next month Winter time starts and setting a meeting now for that time is where it goes wrong. The calendar is set to GMT +2 Berlin Commented Oct 2, 2022 at 13:54
  • 1
    Remember that Europe changes to daylight savings time earlier then for example the USA. Don't add a time zone to the insert let it insert it in the time zone of the calendar that being GMT +2. Google will calculate it properly. If you try and force a timezone its going to try and convert it to the proper time, but with it being close to daylight savings time i suspect you are just going to confuse it. Commented Oct 2, 2022 at 16:34

1 Answer 1

0

My solution was the following:

When uploading an Event via the API, you have to take care of the Timezone offset and possibly also of Daylight Saving Time.

My Classes are using LocalDateTime to take care of the scheduling, so this had to be translated to DateTime (com.google.api.client.util) to create the Event.

For this I have a small function:

 private static DateTime localToDateTime(LocalDateTime time){
        //create a ZonedDateTime using TIMEZONE_NAME static
        ZoneId zoneId = ZoneId.of(TIMEZONE_NAME);   //eg "Europe/Berlin"
        ZonedDateTime zonedDateTime = time.atZone(zoneId);

        //create a string format eg: 2022-06-02T15:25:38T+02:00
        String dateString = zonedDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZZZZZ"));

        //create DateTime for output
        DateTime dateTime = new DateTime(dateString);

        return dateTime;
    }

ZonedDateTime zonedDateTime = time.atZone(zoneId); takes care of the offset, creating the suitable offset for summer or winter time.

This is used by my Event building function:

public static Event buildEvent(String summary, LocalDateTime start, LocalDateTime end){

        DateTime startDateTime = localToDateTime(start);

        EventDateTime eventStart = new EventDateTime();
        eventStart.setDateTime(startDateTime);
        eventStart.setTimeZone(TIMEZONE_NAME);

        DateTime endDateTime = localToDateTime(end);

        EventDateTime eventEnd = new EventDateTime();
        eventEnd.setDateTime(endDateTime);
        eventEnd.setTimeZone(TIMEZONE_NAME);

        Event event = new Event();
        event.setSummary(summary);
        event.setStart(eventStart);
        event.setEnd(eventEnd);

        return event;
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.