Search code examples
javascriptnode.jsgoogle-calendar-apimernutc

Why does Google Calendar API insert my event 4 hours earlier than the date/time that I've given it using Node.js?


I have finally got the google calendar api to insert events into my calendar with Node.js, but the event is inserted 4 hours earlier than the start time that I've given it.

Here's what I've done to get it to insert. In this example: the date variable is '2022-05-18' and the time variable is '17:18' and then when I console.log the apptDate variable, the output is 2022-05-18T17:18:00.000Z

but the event is inserted in my calendar on 2022-05-18 at 13:18.

export const insertGoogleCalendarEvent = async (req, res)=> {
    try{
    const {firstName, lastName, date, time, duration} = req.body

    const apptDate = new Date(`${date}T${time}:00.000Z`).toISOString()

    const SCOPES = ['https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/calendar.events']
    const GOOGLE_PRIVATE_KEY = process.env.GOOGLE_PRIVATE_KEY
    const GOOGLE_CLIENT_EMAIL = process.env.GOOGLE_CLIENT_EMAIL
    const GOOGLE_PROJECT_NUMBER = process.env.GOOGLE_PROJECT_NUMBER
    const GOOGLE_CALENDAR_ID = process.env.GOOGLE_CALENDAR_ID

    let endDateTime = ''
    if (duration === '60') {
        let newDate = new Date(apptDate)
        newDate.setHours(newDate.getHours() + 1)
        endDateTime = newDate.toISOString()
    } else if (duration === '75') {
        let newDate = new Date(apptDate)
        newDate.setMinutes(newDate.getMinutes() + 75)
        endDateTime = newDate.toISOString()
    } else if (duration === '90') {
        let newDate = new Date(apptDate)
        newDate.setMinutes(newDate.getMinutes() + 90)
        endDateTime = newDate.toISOString()
    }

    const event = {
        'summary': `${firstName} ${lastName}`,
        'start': {
            'dateTime': `${apptDate}`,
            'timeZone': 'Canada/Eastern'
        },
        'end': {
            'dateTime': `${endDateTime}`,
            'timeZone': 'Canada/Eastern'
        }
    }

    const jwtClient = new google.auth.JWT(
        GOOGLE_CLIENT_EMAIL,
        null,
        GOOGLE_PRIVATE_KEY,
        SCOPES
    )

    const calendar = google.calendar({
        version: 'v3',
        project: GOOGLE_PROJECT_NUMBER,
        auth: jwtClient
    })

    
        calendar.events.insert({
            calendarId: GOOGLE_CALENDAR_ID,
            resource: event,
        }, {
            function (err, event) {
                if (err) {
                    console.log('this is an error', err)
                    return
                }
                console.log('Event created:', event.htmlLink);
            }
        })
    } catch {
        console.log('error')
    }
}

Solution

  • One reason could be the .00Z part at the end of your appDate variable as it refers to the UTC time zone (Z means UTC or Zulu time). Try to set the needed timezone by using the format -04:00 (Canada/Eastern) at the end.

    Example

    const apptDate = new Date(`${date}T${time}:00-04:00`).toISOString()
    

    Update

    After reviewing the problem again, I think the API adjusted the date and time you have set in the apptDate variable (.000Z, UTC) to the timezone you specified in the timeZone option. In this case, it's Canada/Eastern, UTC-4 hours, so it removed 4 hours from what you have set.

    The dateTime documentation says

    The time, as a combined date-time value (formatted according to RFC3339). A time zone offset is required unless a time zone is explicitly specified in timeZone.

    So a cleaner approach would be to use the apptDate as it is (UTC), without the timeZone option.

    Example

    const apptDate = new Date(`${date}T${time}:00.000Z`).toISOString()
    
    ...
    
    'start': {
            'dateTime': `${apptDate}`
        },
        'end': {
            'dateTime': `${endDateTime}`
        }
    

    More information

    Calendar API documentation