I just currently changed my application to use the PST time zone. However, a lot of my application has code that uses Time.now which is still stuck in UTC:
irb(main):012:0> Time.now
=> 2012-12-27 05:03:16 +0000
Time.current on the other hand, seems to have the correct timezone usage:
irb(main):013:0> Time.current
=> Wed, 26 Dec 2012 21:03:42 PST -08:00
Instead of going through my entire app and changing every instance of Time.now, does it make sense to somehow alias Time.now to use Time.current instead? Is there a better way of handling this in my application so I don't have to modify everywhere I use Time.now since it is not using my app's configured timezone?
From my point of view, this kind of monkey patching should be avoided: Using 'Replace All In Path' Time.now => Time.current is not any harder to do in almost any editor, but you save your debugging time in future hunting some weird bugs in 3rd parties or people working on the same project with your.
If you are using ubuntu, try find/replace with perl
perl -pi -e 's/Time\.now/Time\.current/' *
Related
I have a non-ActiveRecord server which is sending data to another service. That server expects to receive instructions including UTC in the format: "%Y-%m-%d %H:%M:%S.%L". I already have an time_format.rb initializer that overrides Time::DATE_FORMATS[:default] Is there a way I can configure my server so that Time.now.to_s will by default print UTC time, without me having to specify Time.now.utc every time I call it? I'm using ruby 2.0.0 and Rails 4.
I tried adding config.time_zone = 'London' to config/application.rb but that did not work.
I don't think ActiveRecord should have anything to do with it, but maybe I'm misunderstanding. Like Sergio said, set your applications timezone to UTC.
Here's my Rails app. My computer is in PST. My Rails app is set to UTC.
> Time.now
=> 2014-01-22 21:52:38 -0800
> Time.zone.name
=> "UTC"
> Time.zone.now
=> Thu, 23 Jan 2014 05:52:43 UTC +00:00
> Time.now.utc
=> 2014-01-23 05:52:45 UTC
I would strongly advise not overriding Time.now. That can only lead to the dark side.
A general purpose solution that works for any Ruby application:
module TimeClassExtensions
def now
super.utc
end
end
Time.singleton_class.prepend(TimeClassExtensions)
I have a backend written in RoR, and I need to manage many requests from different peers around the world. I have the following questions:
Is it proper to change the config.timezone for each request ?
If yes:
Assuming that 2 requests arrive on my server at the same time. Will the timezone be different for both ? (Means, will there be two differents config.timezone ?)
I don't find any way to set the config timezone with desired UTC, like Time.zone = 'UTC+X'
If no:
Do you know any way to manage it easily and properly ? I have a lot of timezone operations to do, then it would be easier to set it in configuration.
Based on the answers to this question:
Convert Time from one time zone to another in Rails
It seems like using config.timezone is a bad idea due to threading issues.
I would recommend using the ActiveSupport TimeZone and TimeWithZone classes.
This allows you to do things along the lines of:
# Return the simultaneous time in Time.zone or the specified zone
Time.now.in_time_zone # => Tue, 13 Jul 2010 01:20:55 EDT -04:00
Time.now.in_time_zone(Time.zone) # => Tue, 13 Jul 2010 01:20:55 EDT -04:00
Time.now.in_time_zone("Asia/Vladivostok") # => Tue, 13 Jul 2010 16:20:55 VLAST +11:00
Time.now.in_time_zone(-3.hours) # => Tue, 13 Jul 2010 02:20:55 BRT -03:00
# Switch to a given timezone within a block
Time.use_zone "Asia/Vladivostok" do
Time.zone.now # => Tue, 13 Jul 2010 16:20:55 VLAST +11:00
end
Sample code is from http://ofps.oreilly.com/titles/9780596521424/active-support.html
Take a look under 'Time Zone Conversions'
Not a good idea to change config.timezone for each request, but yes, timezone should be handled on per request basis.
Check out the excellent & comprehensive blogpost titled Working with time zones in Ruby on Rails by the folks at elabs for advice on how to deal with multiple timezones.
Ryan Bates' revised version of Time Zones RailsCasts episode is another good resource.
I have a following issue - I'm not using config.time_zone, so it should default to my server time zone (if I understand it correctly).
And in my rails console when I do something like
'Oct 12, 2012'.to_datetime
it returns
Fri, 12 Oct 2012 00:00:00 +0000
but when I run
'Oct 12, 2012'.to_date.end_of_day
I get the time zone I actually need:
2012-10-12 23:59:59 -0400
Do you have any ideas why that can happen and how I can get it to work in the same time zone?
I found this link - https://rails.lighthouseapp.com/projects/8994/tickets/864-string-to_datetime-doesn-t-take-into-account-timezone-or-second-fractions, but I thought it should be fixed.
Thanks!
It's likely that Rails 2.3.14 will be the end of the line for the Rails 2.3 series unless a major security update is required. This will likely go unpatched.
Maybe using to_date produces different results than to_datetime, so you may be able to work around this somehow.
Don't forget you can also tweak the time-zone of any DateTime object if required.
I've got a Rails 3.2.6 app running on Ruby 1.8.7. The app is configured to use central European time (i.e. UTC+2) as its time zone, and in my initializers, I monkey-patch Time and DateTime with some custom functionality.
The odd thing is, that in my monkey-patched methods, the Time/DateTime instances act as if they're UTC (but using the time zone-adjusted value), but elsewhere in the app they respect the time zone config.
So, as an example, in config/initializers/monkey_patching.rb I have the following
module MonkeyPatching
def foo
inspect
end
end
class Time
include MonkeyPatching
end
class DateTime
include MonkeyPatching
end
Now, elsewhere in the app (or in the rails console), here's what I get
model.created_at.inspect #=> "Mon, 24 Sep 2012 15:06:34 CEST +02:00" (correct!)
model.created_at.foo #=> "Mon Sep 24 15:06:34 UTC 2012" (all wrong!)
So, calling inspect "directly" on model.created_at gives me the correct, timezone-adjusted result. But calling the patched-in method foo - which also just calls inspect! - treats the time as UTC, even though it isn't.
To add to my confusion, this only happens with model attributes. I.e. in the rails console, I get identical - and correct - results for DateTime.now.inspect and for DateTime.now.foo. But doing the same for a DateTime attribute, give me the strange behavior seen above.
Any idea why this happens (and how to fix it)?
Rails uses ActiveSupport::TimeWithZone for time attributes, not regular Ruby Time. Try to patch ActiveSupport::TimeWithZone too.
class ActiveSupport::TimeWithZone
include MonkeyPatching
end
I know this is a bad idea, but I have lots of legacy code and I want to run through some historical batch jobs. I dont want to change the systems date because other stuff runs on the same system. Is there any way that I can change the value that Date.today will return for the life of a given process only. The idea here is to rewind and run some older batch scripts that were used to work off of Date.today.
thanks
Joel
You can either monkey-patch Ruby like Nikolaus showed you, or can use the TimeCop gem. It was designed to make writing tests easier, but you can use it in your normal code as well.
# Set the time where you want to go.
t = Time.local(2008, 9, 1, 10, 5, 0)
Timecop.freeze(t) do
# Back to the future!
end
# And you're back!
# You can also travel (e.g. time continues to go by)
Timecop.travel(t)
It's a great, but simple piece of code. Give it a try, it'll save you some headaches when monkeypatching Date and Time yourself.
Link: https://rubygems.org/gems/timecop
you can redefine the 'today' class-method of the Date class
class Date
def Date.today
return Date.new(2000,1,1)
end
end
this would fix Date.today to the 2000-01-01.
If redefining Date.today seems too hacky, you can try delorean
From the github page:
require 'delorean'
# Date.today => Wed Feb 24
Delorean.time_travel_to "1 month ago" # Date.today => Sun Jan 24
Delorean.back_to_the_present # Date.today => Wed Feb 24