diff --git a/app/models/user_option.rb b/app/models/user_option.rb index d3d0a783d42..0c73533ac12 100644 --- a/app/models/user_option.rb +++ b/app/models/user_option.rb @@ -195,6 +195,20 @@ class UserOption < ActiveRecord::Base email_messages_level == UserOption.email_level_types[:never] end + def self.user_tzinfo(user_id) + timezone = UserOption.where(user_id: user_id).pluck(:timezone).first || 'UTC' + + tzinfo = nil + begin + tzinfo = ActiveSupport::TimeZone.find_tzinfo(timezone) + rescue TZInfo::InvalidTimezoneIdentifier + Rails.logger.warn("#{User.find_by(id: user_id)&.username} has the timezone #{timezone} set, we do not know how to parse it in Rails, fallback to UTC") + tzinfo = ActiveSupport::TimeZone.find_tzinfo('UTC') + end + + tzinfo + end + private def update_tracked_topics diff --git a/spec/models/user_option_spec.rb b/spec/models/user_option_spec.rb index 19a9ab5031d..cc4db584751 100644 --- a/spec/models/user_option_spec.rb +++ b/spec/models/user_option_spec.rb @@ -166,4 +166,28 @@ describe UserOption do end end + + describe '.user_tzinfo' do + fab!(:user) { Fabricate(:user) } + + context 'user with valid timezone given' do + before do + user.user_option.update(timezone: 'Europe/Paris') + end + + it 'returns the expect timezone' do + expect(UserOption.user_tzinfo(user.id)).to eq(ActiveSupport::TimeZone.find_tzinfo('Europe/Paris')) + end + end + + context 'user with invalid timezone given' do + before do + user.user_option.update(timezone: 'Catopia/Catcity') + end + + it 'fallbacks to UTC' do + expect(UserOption.user_tzinfo(user.id)).to eq(ActiveSupport::TimeZone.find_tzinfo('UTC')) + end + end + end end