Last active
December 21, 2015 23:39
-
-
Save itchy/6383770 to your computer and use it in GitHub Desktop.
Setting I18n localizations to format times based on user's timezone
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class ApplicationController < ActionController::Base | |
| around_filter :set_i18n_locale_from_current_user | |
| def set_i18n_locale_from_current_user | |
| org_timezone = I18n.current_timezone | |
| if current_user | |
| I18n.current_timezone = current_user.timezone | |
| end | |
| yield | |
| ensure | |
| I18n.current_timezone = org_timezone | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # From | |
| # https://gist.github.com/alexisbernard/179712 | |
| # with updates including | |
| # _date_format(str, format) | |
| # to allow /, - or . as separators | |
| # AND | |
| # match ruby params for _parse && parse | |
| # https://gist.github.com/itchy/6383770 | |
| class Date | |
| class << self | |
| def _date_format(str, format) | |
| format ||= :default | |
| date_format = I18n.translate("date.formats.#{format}") | |
| date_format[/([\.\/-])/] | |
| format_seperator = $1 | |
| str[/([\.\/-])/] | |
| str_seperator = $1 | |
| date_format.gsub!(format_seperator, str_seperator) if format_seperator && str_seperator | |
| date_format | |
| end | |
| def _parse_with_i18n(str, comp=true, format = :default) | |
| date_format = _date_format(str, format) | |
| date = Date._strptime(str, date_format) || _parse_without_i18n(str) | |
| date = _parse_without_i18n(str) if date[:leftover] | |
| date[:year] += increment_year(date[:year].to_i) if date[:year] | |
| date | |
| end | |
| alias_method_chain :_parse, :i18n | |
| def parse_with_i18n(str, comp=true, start=ITALY, format = :default) | |
| date_format = _date_format(str, format) | |
| date = Date.strptime(str, date_format) | |
| Date.new(date.year + increment_year(date.year), date.month, date.day) | |
| rescue ArgumentError | |
| parse_without_i18n(str) | |
| end | |
| alias_method_chain :parse, :i18n | |
| def increment_year(year) | |
| if year < 100 | |
| year < 30 ? 2000 : 1900 | |
| else | |
| 0 | |
| end | |
| end | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # in initializers | |
| module I18n | |
| def self.current_timezone=(tz='UTC') | |
| Thread.current[:current_time_zone] = ActiveSupport::TimeZone.find_tzinfo(tz) | |
| end | |
| def self.current_timezone | |
| Thread.current[:current_time_zone] || ActiveSupport::TimeZone.find_tzinfo('UTC') | |
| end | |
| module Backend::Base | |
| def localize_with_timezone(locale, object, format = :default, options = {}) | |
| raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime) | |
| object = object.in_time_zone(I18n.current_timezone) if object.respond_to?(:in_time_zone) | |
| localize_without_timezone(locale, object, format, options = {}) | |
| end | |
| alias_method_chain :localize, :timezone | |
| end | |
| end |
Thanks Jens -- I updated the gist to have I18n#current_timezone be thread safe
Update date.rb to match Ruby args
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I wonder if it is thread safe. Variable
@current_time_zoneseems to be a global one because ofself. However, I have not looked for it, but if theI18n.localeis implemented the same way we should do so too.Also function should be named
set_i18n_timezone_from_current_userand not replace theset_I18n_local_from_current_user(typo?).What you do at
module Backend::Baselooks interesting, but that all I can say here.