It is 8:04PM in the Eastern Standard Time Zone (US) on February 5, 2016.
When I run this command
Time.now.today?
#=> false
it returns false.
Why, and how can I correct it? Thanks.
Details:
- Rails 4.0.0
- Ruby 2.2.1p85
- Mac OS X El Capitan
It is 8:04PM in the Eastern Standard Time Zone (US) on February 5, 2016.
When I run this command
Time.now.today?
#=> false
it returns false.
Why, and how can I correct it? Thanks.
Details:
One thing that often confuses people is that Time.now
and Time.current
are rather different objects.
Time.now
returns Ruby library's Time class as it is. It returns the system time.
Time.current
returns Time that's modified by Rails ActiveSupport library. It returns system time modified by Rails time_zone setting.
today?
method is declared in ActiveSupport::TimeWithZone
, and it determines if the given object's time is today based on Time.current
, not Time.now
.
So if your Time.now
and Time.current
have different dates, calling Time.now.today?
will return false.
If both represent the same day, Time.now.today?
will return true.
Time.current.today?
should always return true.
Except for some special cases, it'd be better to avoid Time.now
and use Time.current
all the time in Rails.
I think your issue may be a time zone setting. When you ran this at 8:04PM EST
, that is 1:04AM UTC
, your timezone appears to be set to UTC
hence 1:04AM UTC
is tomorrow (Feb 6, 2016
).
I would check your config/application.rb
and try changing your timezone to Eastern Time (US & Canada)
, It looks from your comment above it's currently set to UTC
(default).
Running commands with (Eastern Time (US & Canada)
:
Time.now
=> 2016-02-05 22:42:08 -0500
Time.now.today?
=> true
Date.today
=> Fri, 05 Feb 2016
Time.zone
=> #<ActiveSupport::TimeZone:0x007f9a1bcffd20 @name="Eastern Time (US & Canada)", @utc_offset=nil, @tzinfo=#<TZInfo::TimezoneProxy: America/New_York>, @current_period=#<TZInfo::TimezonePeriod: #<TZInfo::TimezoneTransitionDefinition: #<TZInfo::TimeOrDateTime: 1446357600>,#<TZInfo::TimezoneOffset: -18000,0,EST>>,#<TZInfo::TimezoneTransitionDefinition: #<TZInfo::TimeOrDateTime: 1457852400>,#<TZInfo::TimezoneOffset: -18000,3600,EDT>>>>
When I run the same commands (UTC
timezone):
Notice that Time.now.in_time_zone
is actually tomorrow, thus Time.now.today? => false
Time.now
=> 2016-02-05 22:27:15 -0500
Time.now.today?
=> false
Time.now.in_time_zone
=> Sat, 06 Feb 2016 03:27:29 UTC +00:00
Date.today
=> Fri, 05 Feb 2016
Date.current.in_time_zone
=> Sat, 06 Feb 2016 00:00:00 UTC +00:00
Time.zone
=> #<ActiveSupport::TimeZone:0x007fa19313f7e0 @name="UTC", @utc_offset=nil, @tzinfo=#<TZInfo::TimezoneProxy: Etc/UTC>, @current_period=#<TZInfo::TimezonePeriod: nil,nil,#<TZInfo::TimezoneOffset: 0,0,UTC>>>>
Perhaps your Rails app is configured (in config/application.rb or config/environments/*.rb) with
config.time_zone = 'UTC'
and your Mac is in EST, or conceivably vice versa. Setting the time zone of a Rails 4.1 app I have handy to 'UTC'
reproduces the problem for me.
If so, the discrepancy happened because, at the time you ran the command, the date was a day later in UTC than in your time zone.
There no #today?
method of Time
in pure ruby, and it was introduced by Rails
. Since Rails uses zone time model, I belive it returns false
because current time have a gap to UTC
(of course rails should be configured for UTC
), to be properly sure that #today?
will always return true
, use Time.zone
construction, so you will get:
Time.zone.now.today? # => true