The ruby docs state that I can pass a timezone to the Time initializer:
zone = timezone("Europe/Athens") # Eastern European Time, UTC+2
Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200
However, when I try calling timezone I get undefined method 'timezone'. Is there a particular require that I need?
The timezone method you are referring to is actually just an example. It doesn't exist in Ruby. I agree, the wording and example is perhaps a bit misleading.
Ruby stdlib passes around timezones as strings, by either passing a timezone UTC offset or name. This is shown in the first example:
You can pass a UTC offset:
Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200
Note the string "+02:00".
Then the "incriminated" example you are referring to:
Or a timezone object:
zone = timezone("Europe/Athens") # Eastern European Time, UTC+2 Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200
The way you should read this example is as if somewhere you have a piece of code, here the hypothetical method timezone, that returns an object representing a TZ that can be provided to the initializer.
A practical example is the following one, using the widely adopted tzinfo library:
[2] pry(main)> require 'tzinfo'
=> true
[3] pry(main)> tz = TZInfo::Timezone.get('America/New_York')
=> #<TZInfo::DataTimezone: America/New_York>
[4] pry(main)> Time.new(2002, 10, 31, 2, 2, 2, tz)
=> 2002-10-31 02:02:02 -0500
[5] pry(main)> Time.new(2002, 10, 31, 2, 2, 2)
=> 2002-10-31 02:02:02 +0100
Note how in the example above the hypothetical method timezone is replaced with the actual code that initializes a new TZ object from tzinfo.
Finally, you can access the timezone setting by calling zone on the Time object. Note that what you get depends on the object you used to initialize the zone. By default it is a string, but if I use tzinfo as in the example below, I get the tzinfo instance.
[6] pry(main)> Time.new(2002, 10, 31, 2, 2, 2, tz).zone
=> #<TZInfo::DataTimezone: America/New_York>
[7] pry(main)> Time.new.zone
=> "CET"
To summarize, there is no timezone method defined (which actually the way it is show in the docs would require it to be defined in Kernel, which would be even more strange in Ruby). It was just a placeholder example.
Indeed the timezone method is undefined. There is a trick though on Unix to convert Time object to any time zone. The timezone("Europe/Athens") is meant to talk to the C library underling the Time class ("zoneinfo" database located in /usr/share/zoneinfo/). So you can temporarily change the "system" time zone for the current process by setting the env variable TZ to an appropriate value.
class Time
def convert_zone(to_zone)
original_zone = ENV["TZ"]
utc_time = dup.gmtime
ENV["TZ"] = to_zone
to_zone_time = utc_time.localtime
ENV["TZ"] = original_zone
return to_zone_time
end
end
t = Time.now
t.convert_zone("Europe/Athens")
This is the equivalent of writing your own timezone method :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With