Skip to content

Instantly share code, notes, and snippets.

@timm-oh
Last active September 27, 2020 10:06
Show Gist options
  • Save timm-oh/ba567b787c05c3390e91678b1682375e to your computer and use it in GitHub Desktop.
Save timm-oh/ba567b787c05c3390e91678b1682375e to your computer and use it in GitHub Desktop.
Simple time zone support

Basic Usage

This is a super easy way to ensure that timestamps/datetimes etc render correctly according to the timezone that the object is in. In our usage we have a time_zone attribute on our models that stores the time zone in a format that we can find with active support. Example American Samoa, for more examples run bundle exec rake time:zones:all in your rails project.

We weren't aiming to display the datetime in a format relative to the user, but rather just display that the time was in X time zone

# lets assume we have an attribute called start_time
class Foo < ApplicationRecord
  include TimeZones
  
  time_zone_aware :start_time
end

foo = Foo.new(start_time: "2020-07-15 14:02:52", time_zone: "Pretoria")
foo.start_time.to_s # 2020-07-15 14:02:52 +0200
foo.time_zone = "Bogota"
foo.start_time.to_s # 2020-07-15 14:02:52 -0500
module TimeZones
extend ActiveSupport::Concern
included do
def self.time_zone_aware(*attrs)
attrs.each do |attribute|
define_method(attribute) do
return unless (value = super())
value.in_time_zone(time_zone)
end
define_method("#{attribute}=") do |time|
if time.is_a?(Hash)
super(Time.find_zone(time_zone).local(*time.values_at(1, 2, 3, 4, 5, 6)))
elsif time.respond_to?(:in_time_zone)
super(time.in_time_zone(time_zone))
else
super(time)
end
end
end
end
end
end
@danini-the-panini
Copy link

Maybe don't call super() twice?

-          return unless super()
-          super().in_time_zone(time_zone)
+          value = super()
+          return unless value
+          value.in_time_zone(time_zone)

Also, what if someone passes a String to the assignment method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment