Default TimeZone with ActiveSupport (without Rails) - ruby

How does the default TimeZone get set in ActiveSupport?
Here's what's happening:
irb -r 'rubygems'
ruby-1.8.7-p174 > require 'active_support'
ruby-1.8.7-p174 > require 'active_support/time_with_zone'
ruby-1.8.7-p174 > Time.zone
ruby-1.8.7-p174 > nil
How do I set that to the current location by default?

in rails it gets set in environment.rb via the rails initializer
Rails::Initializer.run do |config|
config.time_zone = 'Pacific Time (US & Canada)'
# ...
I just did a test and when the config.time_zone is commented out Time.zone will also return nil in the rails project; so I guess there is not a 'default' it just gets set in the initializers
Guessing you already know this will 'work'?
irb -r 'rubygems'
ruby-1.8.7-p174 > require 'active_support'
ruby-1.8.7-p174 > require 'active_support/time_with_zone'
ruby-1.8.7-p174 > Time.zone
ruby-1.8.7-p174 > nil
ruby-1.8.7-p174 > Time.zone = 'Pacific Time (US & Canada)'
ruby-1.8.7-p174 > Time.zone
=> #<ActiveSupport::TimeZone:0x1215a10 #utc_offset=-28800, #current_period=nil, #name="Pacific Time (US & Canada)", #tzinfo=#<TZInfo::DataTimezone: America/Los_Angeles>>
Note: above code is using rails 2.2.2 things maybe be different with newer versions?
editors note: In rails >= 3.0 all monkey patches have been moved to the core_ext namespace, so the above require does not extend Time. For later ActiveSupport versions use the following:
require 'active_support/core_ext/time/zones'

You can set the timezone with values from 2 sources, its own ActiveSupport short list (~137 values, see ActiveSupport::TimeZone.all to fetch them) or from the IANA names (~ 590 values). In this last case you can use the tzinfo gem (a dependency of ActiveSupport) to get the list or to instance a TZInfo::TimezoneProxy :
e.g.
ActiveSupport::TimeZone.all.map &:name
Time.zone = ActiveSupport::TimeZone.all.first
Time.zone = ActiveSupport::TimeZone.all.first.name
Time.zone = ActiveSupport::TimeZone.new "Pacific Time (US & Canada)"
Time.zone = ActiveSupport::TimeZone.find_tzinfo "Asia/Tokyo"
List all countries, all timezones:
TZInfo::Country.all.sort_by { |c| c.name }.each do |c|
puts c.name # E.g. Norway
c.zones.each do |z|
puts "\t#{z.friendly_identifier(true)} (#{z.identifier})" # E.g. Oslo (Europe/Oslo)
end
end

Related

undefined method `zone` for Time:Class after requiring active_support/time_with_zone

I'm on Ruby 2.2.1 and have active_support 4.2 installed so I want to use
Time.zone.parse('2007-02-10 15:30:45')
as described here: http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html
But even after requiring active_support and active_support/time_with_zone, I doesn't seem like Time.zone still doesn't work. Observe:
2.2.1 :002 > require "active_support"
=> true
2.2.1 :003 > Time.zone
NoMethodError: undefined method `zone' for Time:Class
2.2.1 :004 > require "active_support/time_with_zone"
=> true
2.2.1 :005 > Time.zone
NoMethodError: undefined method `zone' for Time:Class
What's going on?
The zone class method for the Time class is actually in active_support/core_ext/time/zones. You can require that class if you really want to use Time.zone but a better approach might to require active_support/all
Suggested Solution
require "active_support/all"
If you want to check out the source code fort for active_support look at the github repo
active_support/time_with_zone provides the ActiveSupport::TimeWithZone class, but it doesn't extend the core Time class.
You can require active_support/time instead:
require 'active_support'
require 'active_support/time'
Time.zone = 'Eastern Time (US & Canada)' #=> "Eastern Time (US & Canada)"
Time.zone.parse('2007-02-10 15:30:45') #=> Sat, 10 Feb 2007 15:30:45 EST -05:00
Try
require 'active_support/all'
instead of
require "active_support"

NameError: uninitialized constant Game

I have a file Word.rb
class Word
attr_accessor :word, :letters
def initialize (word)
##word = word
#letters = word.split('').map{|letter| {:letter => letter, :hidden => true} }
end
end
and another file Game.rb, which will use Word.rb
require_relative ('./Word.rb')
require 'pry'
class Game
attr_accessor :guesses, :guessed_letters, :words, :current_word
def initialize (words)
#guesses = 0
#guessed_letters = []
#words = words
#current_word = current_word
end
end
And I'm getting the following error:
NameError: uninitialized constant Game
When I try to create a instance of Game like this:
game = Game.new(['hello', 'sunshine', 'chipmunk', 'twitch'])
I just am not sure what I am doing wrong since I am requiring the Word.rb file that Game.rb will need. All files are on the same level, nothing is in a subdirectory. Interestingly, I do not get this error once I comment the require_relative line out (but of course, I need that file required). I have also tried not using require_relative and simply using require as well as a couple other varieties: parens/no parens, file extension/no file extension, etc. How do I properly require this file? I also have a lovely and robust array of words sitting in another file that I would like to require to be used and passed into Game.new().
Look What I did
$ mkdir test
$ cd test
$ gedit Word.rb
# and copied your content and saved
$ gedit Game.rb
# and copied you content and saved
$ irb
After IRB session run I did following
2.1.1 :001 > game = Game.new(['asd'])
NameError: uninitialized constant Game
from (irb):1
from /home/shiva/.rvm/rubies/ruby-2.1.1/bin/irb:11:in `<main>'
2.1.1 :002 > require 'game'
LoadError: cannot load such file -- game
2.1.1 :004 > require 'Game.rb'
LoadError: cannot load such file -- Game.rb
2.1.1 :005 > require './Game.rb'
=> true
2.1.1 :006 > game = Game.new(['shiva', 'bhusal'])
=> #<Game:0x00000003085428 #guesses=0, #guessed_letters=[], #words=["shiva", "bhusal"], #current_word=nil>
2.1.1 :007 >
Try like this

Setting up Time.zone in Padrino

I am having a trouble setting the default ActiveSupport::TimeZone in my padrino project.
In my boot.rb I have
Padrino.after_load do
Time.zone = 'UTC'
ActiveRecord::Base.default_timezone = :utc
end
My controller file has:
MyApp::App.controllers :post do
get :index do
puts Time.zone # this returns nil
render 'index'
end
end
When I hit the index action I get nil for Time.zone. It seems as though something might be overwriting Time.zone or it isn't loaded properly.
I am able to print out the Timezone after setting it in boot.rb. So I know it was set.
You can set it like this:
Time.zone_default = Time.find_zone!("UTC")
That's all you need, but see below for details.
The above worked for me with activesupport 5.0.2. I looked at how Time.zone is implemented:
class Time
include DateAndTime::Zones
class << self
attr_accessor :zone_default
# Returns the TimeZone for the current request, if this has been set (via Time.zone=).
# If <tt>Time.zone</tt> has not been set for the current request, returns the TimeZone specified in <tt>config.time_zone</tt>.
def zone
Thread.current[:time_zone] || zone_default
end
I then guessed that it might be missing in the current thread with Padrino.
Presumably Time.zone would need to be set once for each thread. For whatever reason, that's not always the case when assigning the zone in Padrino.before_load. I did not dig into this, but I'm sure there's a nicer solution to be found that assigns it in each thread.
If you want per-user time zones, not just a global one for the entire app, you will need to dig further.
In my boot.rb I've got:
Padrino.before_load do
Time.zone = 'UTC'
end
and in my database.rb:
ActiveRecord::Base.default_timezone = :utc
Which having tested in the console seems to work:
ruby-2.1.4$ padrino c
=> Loading development console (Padrino v.0.12.4)
2.1.4 :001 > Time.zone
=> #<ActiveSupport::TimeZone:0x007fbff62ed5c0 #name="UTC", #utc_offset=nil, #tzinfo=#<TZInfo::TimezoneProxy: Etc/UTC>, #current_period=#<TZInfo::TimezonePeriod: nil,nil,#<TZInfo::TimezoneOffset: 0,0,UTC>>>>
2.1.4 :002 > Time.zone.now
=> Tue, 30 Dec 2014 13:14:57 UTC +00:00
2.1.4 :003 > Time.current
=> Tue, 30 Dec 2014 13:15:01 UTC +00:00
2.1.4 :004 > ActiveRecord::Base.default_timezone
=> :utc
N.B. Tested with ruby v2.1.4, padrino v0.12.4, activesupport/activerecord v4.2.0.

Why is Ruby's Date class automatically loaded but DateTime is not?

Using IRB, why are the Date & Time classes automatically loaded, but DateTime is not? I have to require 'date', this does not make sense to me because I thought that both Date and DateTime were using the standard library 'date'?
ruby-1.9.2-p290 :001 > Date
=> Date
ruby-1.9.2-p290 :002 > Time
=> Time
ruby-1.9.2-p290 :003 > DateTime
NameError: uninitialized constant Object::DateTime
from (irb):3
from /Users/kamilski81/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
ruby-1.9.2-p290 :004 > require 'date'
=> true
ruby-1.9.2-p290 :005 > require 'date'
=> false
ruby-1.9.2-p290 :006 > DateTime
=> DateTime
In IRB, include this line: require 'date' then you will be able to use DateTime.
irb(main):000:0> DateTime.class
NameError: uninitialized constant DateTime
from (irb):0
from /path/to/ruby/irb:12:in '(main)'
irb(main):001:0> require 'date'
=> true
irb(main):002:0> DateTime.class
=> Class
Worked for me when first initializing with require 'date'.
Being a little more curious, I tried:
$ ruby -e 'puts DateTime.class'
-e:1:in `<main>': uninitialized constant Object::DateTime (NameError)
[~, kamilski81#mac]
$ ruby -e 'puts Date.class'
-e:1:in `<main>': uninitialized constant Object::Date (NameError)
$ ruby -e 'puts Time.class'
Class
So it makes me think that it's an irb issue that automatically loads 'date'.

How do I use an ActionView::Helper in a Ruby script, outside of Rails?

I am looking to use ActionView::Helpers::NumberHelper from a Ruby script.
What all do I need to require etc.?
~> irb
ruby-1.9.2-p180 :001 > require 'action_view'
=> true
ruby-1.9.2-p180 :002 > ActionView::Base.new.number_to_currency 43
=> "$43.00"
As of Rails 3.2.13, you can do the following:
class MyClass
include ActionView::Helpers::NumberHelper
def my_method
...
number_with_precision(number, precision: 2)
...
end
end
You might need to require 'action_view' too.
Edit: This answer is still valid in Rails 4.2.3.

Resources