module HasZone

Constants

VERSION

Public Class Methods

has_zone(options = { with: :time_zone }) click to toggle source

This allows the model has the ability to store TimeZone. Usage: has_zone with: :time_zone

It defines the following methods:

:zone Public: Returns the Rails Time Zone.

:zone=(identifier) Public: Sets the TimeZone by TZinfo identifier.

identifier - Time Zone identifier

# File lib/has_zone/has_zone.rb, line 21
def self.has_zone(options = { with: :time_zone })
  define_method(:zone) do
    return nil if send(options[:with]).nil?
    @zone ||= ::ActiveSupport::TimeZone.tzids_map[send(options[:with])].try(:name)
  end

  define_method(:zone=) do |tz|
    zone = tz.is_a?(String) ? ::ActiveSupport::TimeZone.new(tz) : tz
    send "#{options[:with]}=".to_sym, zone.try(:identifier)
  end

  define_method("#{options[:with]}=".to_sym) do |tz|
    # Since we memoize the time zone, we need to reset it if the time zone has changed
    @zone = nil
    write_attribute(options[:with], tz)
  end

  define_method(:alias_time_zone) do
    if send(options[:with]) == "UTC"
      send "#{options[:with]}=".to_sym, "Etc/UTC"
    elsif ::ActiveSupport::TimeZone.tzids_map.keys.exclude? send(options[:with])
      Rails.logger.warn("Time zone #{send(options[:with])} is not a valid time zone.") if defined? Rails
    end
  end

  before_validation :alias_time_zone

end