2012-04-11 126 views
4

我想要ActiveSupport::TimeWithZone的實例的日期部分。我使用to_date函數,但它返回一天前的日期。ActiveSupport :: TimeWithZone#to_date返回錯誤的日期

例如,如果日期時間爲2012-04-11 09:05:00 UTC,如果我叫to_date然後返回2012-04-102012-04-11

而且我不使用特定的時區(默認爲UTC)

的應用程序在運行Ruby 1.8.7Rails 3.0.2

誰能告訴我爲什麼它給出錯誤的日期?也請建議我,如果有更好的方法來從給定DateTime(的ActiveSupport::TimeWithZone實例)

編輯獲取日期(的Date實例)部分: 有人在這裏也面臨着同樣的問題http://pastebin.com/sn8ExZiQ

注意Time.zone返回'UTC'

+0

什麼是Time.zone的價值? – 2012-04-11 08:51:56

+0

@FrederickCheung Time.zone return UTC – 2012-04-11 09:43:12

+0

你調用'to_date'的'ActiveSupport :: TimeWithZone'對象的'zone'的輸出是什麼? – shime 2012-04-11 09:59:31

回答

1

謝謝Jignesh。在這裏,我分享你的發現和解決方案。

可能有一些gem覆蓋to_date的實現,它可能會被錯誤地實現,並且這個被覆蓋的版本可能會被調用。

在我的情況的罪魁禍首是ruby-units寶石

根本原因ruby-units寶石包括在應用程序的Gemfile中

問題分析

的Gemfile

# Ruby-units overrides String class #to method, hence placed before Rails 
gem "ruby-units" # Loads first and then rails is loaded 

gem "rails", "3.0.11" 

.. 
.. 

time.rb文件(紅寶石單元寶石基本代碼)

.. 
.. 

unless Time.instance_methods.include?(:to_date) 
    # :nocov_19: 
    # @return [Date] 
    def to_date 
    x=(Date.civil(1970,1,1)+((self.to_f+self.gmt_offset)/86400.0)-0.5) 
    Date.civil(x.year, x.month, x.day) 
    end 
    # :nocov_19: 
end 

.. 
.. 

比方說在UTC時區即當前時間是 Wed, 11 Apr 2012 10:12:17 UTC +00:00ActiveSupport::TimeWithZone 實例表示。 從rails應用程序執行<TimeWithZone>.to_date時,它返回 日期2012-04-10這是不正確的。

上述不正確的行爲涉及罪魁禍首是由ruby-units寶石

下面提供to_date方法 的實現是示例程序來證明上述不正確的行爲。to_date方法與ruby-units gem實現的方法相同,不同的是方法中增加了一個參數,即date_time,實現中的self被參數 'date_time'取代。

樣品Ruby程序,以確認上述發現:

require 'rubygems' 
require 'active_support/all' 

class TestDT 
def to_date(date_time) 
    #x=(Date.civil(1970,1,1)+((self.to_f+self.gmt_offset)/86400.0)-0.5) 
    x=(Date.civil(1970,1,1)+((date_time.to_f+date_time.gmt_offset)/86400.0)-0.5) 
    Date.civil(x.year, x.month, x.day) 
end 
end 

tdt = TestDT.new 
utc_time = Time.now.in_time_zone('UTC') 
puts tdt.to_date(utc_time) 

輸出(日期在寫這篇的時間爲週三,11 Apr 2012 08:35:12 UTC +00:00):

$ ruby test_date_time.rb 
2012-04-10 

解決方案:

  1. 刪除0123中的ruby-units寶石或加載後軌寶石
  2. 解決辦法:不要執行datetime.to_date的,使用datetime.to_s.to_date
相關問題