Class: RailsClientTimezone::Filter

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_client_timezone/filter.rb

Class Method Summary collapse

Class Method Details

.filter(controller, &block) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/rails_client_timezone/filter.rb', line 5

def self.filter(controller, &block)
  cookies = controller.send(:cookies)
  
  current_time_zone = if Setting.mode == :browser
    get_time_zone_by_browser_offset(cookies[:utc_offset_summer], cookies[:utc_offset_winter], cookies[:last_known_tz])
  elsif Setting.mode == :ip
    get_time_zone_by_ip(controller, cookies[:last_known_tz])
  else
    get_time_zone_by_smart(controller, cookies[:utc_offset_summer], cookies[:utc_offset_winter], cookies[:last_known_tz])
  end
  controller.response.set_cookie(:last_known_tz, {:path => "/", :value => current_time_zone.name})

  Time.use_zone(current_time_zone) do
    yield
  end
end

.get_time_zone_by_browser_offset(utc_offset_summer, utc_offset_winter, last_known_tz) ⇒ Object

Returns the time zone based on parsed utc_offset_summer and utc_offset_winter Returns the default TimeZone if none is resolved



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/rails_client_timezone/filter.rb', line 24

def self.get_time_zone_by_browser_offset(utc_offset_summer, utc_offset_winter, last_known_tz)
  # ActiveSupport::TimeZone[offset] - will return the first time zone that matches the offset.
  # But, we need to get the exact time zone inorder to reflect the daylight savings.
  # So, we get the user's time zone exactly by matching the summer offset and winter offset both.
  [ActiveSupport::TimeZone[last_known_tz.to_s], ActiveSupport::TimeZone.all].flatten.compact.detect(ifnone = Time.method(:zone_default)) do |zone|
    Time.use_zone(zone.name) do
      if utc_offset_summer.present? && utc_offset_winter.present?
        (Time.zone.parse(Setting.mid_summer_date_str).utc_offset == utc_offset_summer.to_i && Time.zone.parse(Setting.mid_winter_date_str).utc_offset == utc_offset_winter.to_i)
      else
        (Time.zone.name == last_known_tz.to_s)
      end
    end
  end
end

.get_time_zone_by_ip(controller, last_known_tz = nil) ⇒ Object

Returns the time zone based on IP address Returns the default TimeZone if none is resolved



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rails_client_timezone/filter.rb', line 41

def self.get_time_zone_by_ip(controller, last_known_tz = nil)
  return ActiveSupport::TimeZone[last_known_tz] if last_known_tz && ActiveSupport::TimeZone[last_known_tz]
  begin
    ip_addr = controller.request.remote_ip
    geo_timezone = GeoIP.new(Setting.geoip_data_path).city(ip_addr) ? GeoIP.new(Setting.geoip_data_path).city(ip_addr).timezone : nil
    timezone_name = geo_timezone && ActiveSupportExt.format(geo_timezone) ? ActiveSupportExt.format(geo_timezone) : Time.zone_default.name
  rescue Exception => e
    ActiveSupport::TimeZone[Time.zone_default.name]
  end
  ActiveSupport::TimeZone[timezone_name]
end

.get_time_zone_by_smart(controller, utc_offset_summer, utc_offset_winter, last_known_tz) ⇒ Object

Returns the time zone using both ip address and browser offset Returns the default TimeZone if none is resolved



55
56
57
58
# File 'lib/rails_client_timezone/filter.rb', line 55

def self.get_time_zone_by_smart(controller, utc_offset_summer, utc_offset_winter, last_known_tz)
  last_known_tz_val = last_known_tz ? last_known_tz : get_time_zone_by_ip(controller).name
  get_time_zone_by_browser_offset(utc_offset_summer, utc_offset_winter, last_known_tz_val)
end