Recently I worked on an appointment booking(Telemedicine) feature for one of our healthcare projects. Creating an appointment is all about Date/Time and the challenging part is timezone.
It is so easy to get this done, only if you have the right understanding of how to handle Date and Time along with timezone.
Always save Date/Time in UTC in your database, this way you would be able to convert the DateTime to any timezone you want.
Rails ActiveSupport::TimeZone serves as a wrapper around TZInfo::Timezone instances.
When you get Date, Time and Timezone from the user, set the timezone first, There are two ways to do that in Rails
Option 1 Time.zone = timezone Option 2 Time.use_zone(timezone) do #Play with the date & time end
If you want to set the timezone for a particular block go with option 2.
Timezone view helper
Here comes some interesting part of timezones, the daylight savings time.
Rails provide time_zone_select helper to list all the timezones but there is one small thing we have to notice about the Daylight savings.
Let’s take Pacific Time (US & Canada)
In case of using the helper, you will always see Pacific Time (US & Canada)(GMT-08:00) but during the DayLight time it should be Pacific Time (US & Canada)(GMT-07:00)
To fix this we can go with a custom timezone select box with the list of timezones. e.now.formatted_offset will take care of the Daylight offset based on the current time.
timezones = ActiveSupport::TimeZone.all.map{|e| ["#{e.name}(GMT#{e.now.formatted_offset})", e.name]} <%= select :user, :timezone, timezones, select_attributes, field_attributes %>
Save and Retrieve Date and Time
Now save the date and time in the database by mentioning the timezone.
To parse date and time, instead of Time.parse use Time.zone.parse
Time.use_zone(timezone) do appointment.event_datetime = Time.zone.parse("#{date.year}-#{date.month}-#{date.day} #{start_time}") appointment.save end
It’s all set, the date and time are saved in UTC based on the user-selected timezone( along with daylight). Now you can easily retrieve the date and time for any timezone you want using
(appointment.event_datetime).in_time_zone(timezone) or Time.use_zone(timezone) do appointment.event_datetime end or Time.zone = timezone appointment.event_datetime
Few tips while working on timezone
Time.parse('2020-02-12 05:33:39") -> Time.zone.parse('2020-02-12 05:33:39") Time.strptime(string, format) -> Time.strptime(string, format).in_time_zone Time.now -> Time.zone.now Time.today -> Time.zone.today
I hope this will help you to understand and implement timezone based feature on your application.