我有下面的代码片段:
class Foo
include DataMapper::Resource
property :id, Serial
property :timestamp, DateTime
end
我只想将当前时间转换为ms:
class Time
def to_ms
(self.to_f * 1000.0).to_i
end
end
def current_time
time = Time.now
return time.to_ms
end
time = current_time # => 1352633569151
但是当我用上面的时间戳保存Foo时,它就不能保存到数据库中,我也没有收到任何错误消息。
foo = Foo.new
foo.timestamp = time
foo.save
你知道吗?
3条答案
按热度按时间esbemjvw1#
你是否使用正确的格式为您的
:datetime
属性?应该是这样的:
或“本机”DateTime对象,而不进行任何转换。
DataMapper将根据所使用的适配器将其转换为相应的值。
此外,要在保存项目时引发异常,请执行以下操作:
这是一个全局设置,即所有模型都会引发异常。
来让模型表现得像这样:
http://datamapper.org/docs/create_and_destroy.html
请参阅“在保存失败时引发异常”一章
顺便说一句,要在保存之前查看项目的错误,请使用和
item.valid?
和item.errors
我复制了你的代码,得到了以下错误:
参见live demo here
ql3eal8s2#
PostgreSQL的数据类型应该是
timestamp
ortimestamptz
。但这与你正在做的事情相矛盾。你取epoch值并乘以1000。你必须将其保存为bigint
或一些numeric type。基础知识:
我会将值保存为
timestamptz
。(没有乘法。)如果需要,您可以随时提取ms。如果需要将Unix epoch值转换回时间戳,请用途:
保存“现在”即可
如果你真的想保存“现在”,也就是当前的时间点,那么就让Postgres来帮你保存吧。只要确保数据库服务器有一个可靠的本地时间即可。(可以在服务器上安装
ntp
。)这样通常更可靠,更准确,更简单。将timestamp列的
DEFAULT
设置为now()
或CURRENT_TIMESTAMP
。如果你想要
timestamp
而不是timestamptz
,你仍然可以使用now()
,它会根据服务器的时区设置转换为“本地”时间-实际上与LOCALTIMESTAMP
相同。或者,获取给定时区的时间:或者,在您的特定情况下,因为您似乎只想要三个小数位:
now()::timestamp(3)
,或CURRENT_TIMESTAMP(3)
,或CURRENT_TIMESTAMP(3) AT ZIME ZONE 'Europe/Vienna'
,或date_trunc('ms', LOCALTIMESTAMP)
。后者 * 截断 *,而其他 * 舍入 *。通常,您希望截断。请参阅:或者,如果将列的类型定义为
timestamp(3)
,则所有时间戳值都将强制为该类型,并自动舍入为3个小数位:该值是在**
INSERT
上自动设置的,您甚至不必提及该列。如果你想这样做
ON UPDATE
**,添加一个TRIGGER
如下:触发功能:
触发器:
在Postgres 10或更早版本中,使用关键字
PROCEDURE
而不是FUNCTION
。请参阅:现在,一切都自动工作。
nkcskrwz3#
我对PostgreSQL不太熟悉,但为什么要将Fixnum(
time
)分配给timestamp
(这是一个DateTime)?您的模型在生成SQL之前一定无法将time
转换为正确的DateTime值。尝试
foo.save!
。我很肯定你会看到一个错误,要么是PostgreSQL报告的,说1352633569151
不是表列的有效值,要么是你的模型说它不能将1352633569151
解析为有效的DateTime。foo.timestamp = Time.now
或foo.timestamp = '2012-11-11 00:00:00'
是可行的。