Reputation: 6211
I am building an application in which users enter data on a form, including a date and time, which then populates their Google Calendar with events based on that information. I can't seem to figure out how to handle time zones, and I'm not sure whether the issue is with Ruby/Rails or the Google Calendar API, both of which have documentation which is... not great.
If I enter 10:00AM on my form, the Google Calendar invite is created at 6:00 AM. I'm at -0400 from UTC, which accounts for that. Ideally, I'd like for the user to not have to worry about time zones at all, but if I have to have my user choose a time zone from a dropdown it's not the end of the world.
Here's my form (which I am free to modify in any way as long as I have a way for the user to enter a time and date):
<%= date_field(:calendar, "start_date", min: Date.today, :value => Time.now.strftime('%Y-%m-%d'), :class=>'form-control') %>
<input type="time" id="calendar_start_time" name="calendar[start_time]" min="9:00" max="18:00" value="10:00" step="900" />
<%= select("calendar", "time_zone", @timezones, {:class=>'form-control'}) %>
And my controller:
def create
calendar_id = params[:calendar][:id]
start_date = params[:calendar][:start_date]
start_time = params[:calendar][:start_time]
time_zone = params[:calendar][:time_zone]
lesson_hash = get_module_lectures(module_number)
# Time.zone = 'America/New_York'
lesson_hash.each do |days_from_start, lesson_name|
lesson_datetime = Time.parse("#{start_date} #{start_time}").advance(:days => days_from_start)
new_event(calendar_id, lesson_datetime, lesson_name, time_zone)
end
redirect_to calendars_url
end
def new_event(calendar_id, lesson_datetime, lesson_name, time_zone)
client = Signet::OAuth2::Client.new(client_options)
client.update!(session[:authorization])
service = Google::Apis::CalendarV3::CalendarService.new
service.authorization = client
event = Google::Apis::CalendarV3::Event.new({
# start: Google::Apis::CalendarV3::EventDateTime.new(datetime: lesson_datetime),
# end: Google::Apis::CalendarV3::EventDateTime.new(datetime: lesson_datetime.advance(:hours => 1)),
start: {
'date_time': lesson_datetime,
# 'time_zone': 'America/New_York'
},
end:{
'date_time': lesson_datetime.advance(:hours => 1),
# 'time_zone': 'America/New_York'
},
summary: lesson_name
})
service.insert_event(calendar_id, event)
end
As you can see, I've tried hard-coding the time zone in a few places for testing but none of them seem to have any effect on the events created--they're always offset by 4 hours. I'm using Rails 5.2
Upvotes: 3
Views: 669
Reputation: 5690
The DateTime must be set up with the TimeZone:
lesson_hash.each do |days_from_start, lesson_name|
lesson_datetime = ActiveSupport::TimeZone["America/New_York"].parse("#{start_date} #{start_time}").advance(:days => days_from_start)
new_event(calendar_id, lesson_datetime, lesson_name, time_zone)
end
The time needs to be formatted correctly. Try this:
event = Google::Apis::CalendarV3::Event.new(
start: Google::Apis::CalendarV3::EventDateTime.new(date_time: lesson_datetime.to_datetime.rfc3339),
end: Google::Apis::CalendarV3::EventDateTime.new(date_time: lesson_datetime.advance(:hours => 1).to_datetime.rfc3339),
summary: lesson_name
)
service.insert_event(calendar_id, event)
Upvotes: 2