我需要能够保存负日期,但遇到了一个问题:从数据库检索日期时,ActiveRecord 在年份上加 1。
迁移使用t.date
。
这是一个简单的示例:
我创建并保存了一个日期值为 Date.new(-44, 3, 15)
的模型。
插入数据库时,在数据库内部,年份是正确的。手动 psql 检查证实了这一点。
但是,当使用 ActiveRecord 从数据库检索日期时,年份为 -43。
我用谷歌搜索过,但没有结果。知道是什么原因造成的吗?
最佳答案
http://ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/Date.html#method-c-new
...BCE years are counted astronomically. ...the year before the year 1 is the year zero, and the year preceding the year zero is the year -1.
研究这个我以为你发现了 Date#parse
中的缺陷,然后我认为它正在“按设计”工作,现在我不再确定了:(
Date.parse('2015-06-15 CE') == Date.new(2015, 6, 15)
# => true
Date.parse('0000-01-01 CE') == Date.new(0, 1, 1)
# => true
Date.parse('0002-01-01 BCE') == Date.new(-1, 1, 1)
# => true
Date.parse('0000-01-01 CE') == Date.parse('0001-01-01 BCE')
# => true
Date.parse('0001-01-01 BCE') == Date.new(0, 1, 1)
# => true
https://en.wikipedia.org/wiki/Astronomical_year_numbering
The year 1 BC/BCE is numbered 0, the year 2 BC is numbered −1
所以它似乎“按设计”工作,但可能不符合预期
# The year 1 BC/BCE is numbered 0
Date.parse('0001-01-01 BCE') == Date.new(0, 1, 1)
# the year 2 BC is numbered −1
Date.parse('0002-01-01 BCE') == Date.new(-1, 1, 1)
这对您和您的 Rails 应用意味着什么?
用户输入很可能以“0044-03-15 BC”格式作为字符串(参数)提交,并分配给模型属性。
x = Widget.create(date_column: '0044-03-15 BC')
x.date_column
=> Wed, 15 Mar -0043
x.attributes_before_type_cast['date_column']
=> "0044-03-15 BC"
x.attributes_before_type_cast['date_column'].to_date
=> Wed, 15 Mar -0043
猜测to_date
也在使用Date.parse
我真的不确定如何将正确的值存储在 postgres 中,但是 Rails 将在该值上使用 Date.parse
,并在显示用户输入的日期时关闭一年(仅公元前)。
一些可能的 hacky 解决方法
1)将值存储为整数
class Whatever < ActiveRecord::Base
# 'date' column -> the_date stored as an integer
# override the columns 'getter' method
def the_date
the_time = Time.at(self[:the_date])
Date.new(the_time.year, the_time.month, the_time.day)
end
end
# Time#to_i - epoch time
x = Whatever.create(the_date: Time.new(-44, 3, 15, 0, 0, 0).to_i)
2)将年、月、日存储为单独的数据库字段?
class Whatever < ActiveRecord::Base
# 'date' stored as 3 integer columns -> the_date_year, the_date_month, the_date_day
# use this in views, etc...
def the_date
Date.new(the_date_year, the_date_month, the_date_day)
end
end
希望其他人有更好的解决方案......
关于ruby-on-rails - ActiveRecord 添加负日期年份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31077771/