0

我有以下代码片段:

class Foo    
  include DataMapper::Resource
  property :id, Serial
  property :timestamp, DateTime
 end

我只想将当前时间转换为毫秒:

 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

任何想法?

4

3 回答 3

3

您是否为您的:datetime财产使用了正确的格式?

应该是这样的:

DateTime.now.to_s
=> "2012-11-11T14:04:02+02:00"

或“本机” DateTime 对象,没有任何转换。

DataMapper 将根据使用的适配器将其转换为相应的值。

此外,在保存项目时引发异常:

DataMapper::Model.raise_on_save_failure = true 

这是一个全局设置,即所有模型都会引发异常。

仅使某些模型的行为如下:

YourModel.raise_on_save_failure = true

http://datamapper.org/docs/create_and_destroy.html

请参阅“保存失败时引发异常”一章

顺便说一句,在保存之前查看您的项目有什么问题,使用 and item.valid?anditem.errors

foo = Foo.new
foo.timestamp = time
if foo.valid?
  foo.save
else
  p foo.errors
end

我复制了您的代码并收到以下错误:

@errors={:timestamp=>["Timestamp must be of type DateTime"]}

在此处查看现场演示

于 2012-11-11T12:01:38.603 回答
2

PostgreSQL 数据类型将是timestamptimestamp with time zone。但这与你正在做的事情相矛盾。您将 epoch 值乘以 1000。您必须将其保存为integer或一些数字类型

有关在此相关答案中处理 Postgres 中时间戳的更多信息。

我会按timestamp with time zone原样保存值(不乘法)。如果需要,您可以随时从中提取 ms。

如果您需要将 Unix 纪元值转换回时间戳,请使用:

SELECT to_timestamp(1352633569.151);
--> timestamptz 2012-11-11 12:32:49.151+01

只需保存“现在”

如果您真的想保存“现在”,即当前时间点,那么让 Postgres 为您完成。只需确保数据库服务器具有可靠的本地时间 - 安装ntp。这通常更可靠、准确和简单。

DEFAULT时间戳列的 设置为now()CURRENT_TIMESTAMP
如果您愿意timestamptimestamptz您仍然可以使用now(),根据服务器时区设置将其转换为“本地”时间。或者,要获取给定时区的时间:

now() AT ZIME ZONE 'Europe/Vienna'  -- your time zone here

或者,在您的特定情况下,因为您似乎只需要三个小数:now()::timestamp(3)or CURRENT_TIMESTAMP(3)or CURRENT_TIMESTAMP(3) AT ZIME ZONE 'Europe/Vienna'
或者,如果您将列的类型定义为timestamp(3),则所有时间戳值都将强制转换为该类型并自动四舍五入为 3 位小数。

所以这就是你所需要的:

CREATE TABLE tbl (
   -- other columns
  ,ts_column timestamp(3) DEFAULT now()
);

该值是自动设置的INSERT,您甚至不必提及该列。
如果要更新它ON UPDATE,请添加如下触发器

触发功能:

CREATE OR REPLACE FUNCTION trg_up_ts()
  RETURNS trigger AS
$BODY$
BEGIN
   NEW.ts_column := now();
   RETURN NEW;
END
$BODY$ LANGUAGE plpgsql VOLATILE

扳机:

CREATE TRIGGER log_up_ts
BEFORE UPDATE ON tbl
FOR EACH ROW EXECUTE PROCEDURE trg_up_ts();

现在,一切都自动进行。
如果那不是您所追求的,@slivu 的回答似乎很好地涵盖了 Ruby 方面。

于 2012-11-11T12:08:09.463 回答
0

我不熟悉 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'是可以工作的东西。

于 2012-11-11T15:12:04.353 回答