8

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
Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
boulder_ruby
  • 38,457
  • 9
  • 79
  • 100
  • 2
    There is no such method as `Time#today?` in core Ruby. – sawa Feb 06 '16 at 01:10
  • interesting, this is in a rails project. So I'll add the tag.......Yep, just confirmed its a rails method. Will submit an issue on github, but I'm sure there's some configuration settings I can change to correct it for the time being – boulder_ruby Feb 06 '16 at 01:18
  • 1
    What does `Time.zone` return? How about `Date.today`? – Dave Schweisguth Feb 06 '16 at 01:34
  • So strange. `Date.today` returns "Fri, 05 Feb 2016", but `Time.zone` returns the expected `#, @current_period=nil> ` (UTC) – boulder_ruby Feb 06 '16 at 01:53

4 Answers4

7

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.

Harfangk
  • 814
  • 9
  • 18
3

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>>>>
treiff
  • 1,246
  • 14
  • 24
2

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.

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
2

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
Малъ Скрылевъ
  • 16,187
  • 5
  • 56
  • 69