Sequelize - 使用 UNIX 时间戳作为 DATE 字段

6

有没有一种方法可以强制Sequelize使用UNIX时间戳作为默认时间格式,无论是createdAt/updatedAt时间戳还是自定义的Sequelize.DATE字段类型?

谢谢!

P.S. 我正在使用MySQL。

3个回答

7

虽然eggyal的答案是在MySQL中正确的做法,但我们中有些人可能会在需要使用unix时间戳而非日期/时间戳的环境或团队中工作。

我发现一种很好的方法是在sequelize内使用钩子。在每个模型的底部,您可以添加以下代码:

{
        tableName: 'Addresses',
        hooks : {
            beforeCreate : (record, options) => {
                record.dataValues.createdAt = Math.floor(Date.now() / 1000);
                record.dataValues.updatedAt = Math.floor(Date.now() / 1000);
            },
            beforeUpdate : (record, options) => {
                record.dataValues.updatedAt = Math.floor(Date.now() / 1000);
            }
        }
    }

这将插入createdAtupdatedAt 字段作为Unix时间戳。

tableNamehooks字段是模型的选项对象的一部分。当使用.define()时,它是属性对象之后的参数。 - Jordan Dodson

6

在任何时刻,根据国际日期变更线的位置,有两个可能的日期:这意味着从UNIX时间戳转换为日期需要考虑时区。

例如,UNIX时间戳9466848002000年1月1日00:00:00Z。虽然这代表了新千年的第一天在大西洋以东几乎所有地方,但在那个海洋以西的地方仍然是除夕。所以它代表哪个日期?

虽然可以将日期转换为时间戳,但必须定义自己的约定来做到这一点(例如,将给定日期表示为UTC的午夜),否则每个编码可能会以不同的方式表示相同的日期。总的来说,这是一个坏主意,可能会产生各种意想不到的后果。

存在DATE数据类型的原因是:这是存储日期的正确方式。请使用它。


存储Unix时间是一种有效的时间存储方式(一般而言)-从中解释本地日期/时间只是计算本地/季节性偏移量与UTC时间的差别问题。 - rjarmstrong
@rjarmstrong:难道这不就是我的答案所说的吗?我的观点是,OP正在询问如何使用时间戳存储日期(仅限日期)。 - eggyal
2
问题在于你说 DATE 数据类型是存储日期的正确方式 - 这是误导性的。如果你加上类似“在 Sequelize 中推荐使用 DATE 类型”的说明,我很乐意取消我的反对票。不幸的是,根据我的观察,Sequelize 的 DATE 类型也有一个限制,即它不存储毫秒,这可能是时间戳引起兴趣的原因。 - rjarmstrong
@rjarmstrong,我甚至不同意“在Sequelize中推荐使用DATE类型”。这实际上取决于您想要存储什么。当您说要存储“日期”时,必须了解您是想将日期存储为客户端所感知的日期(本地时间、日历中选择的时间),还是想记录一个明确的时间点(无论其客户端表示如何)。通过Unix时间戳,您可以确定确切的时间点。通过日期,您可以确定客户端表示。要同时获取两者,您需要在两种情况下都提供一些额外信息。 - Jānis Elmeris
1
99%的情况下,存储日期的正确方式是将其作为自纪元以来的持续时间,例如UNIX时间戳。然后,当您向用户呈现它时,您可以根据用户的系统设置要求操作系统/浏览器进行格式化。人们过于关注时区,但有些用户甚至没有使用公历日历(!!!)。 - alextgordon

1
不是,或者至少现在还没有。CreatedAt 是使用 Sequelize 中的 utils.now 函数设置的。该函数使用 JavaScript 的 Date 函数,没有其他参数。Squelize 可以被修改以改变它调用 Date 的方式,但是在当前版本中没有这样的代码。请参见 此处
但是,您可以禁用 createdAt 和其他时间戳,并使用原始查询来设置自己的时间戳。然而,这样做会牺牲 Sequelize 的功能。最好的解决方案可能是在使用这些字段之前,在您的业务逻辑中将它们转换为 Unix 时间。

谢谢,我考虑过这样的解决方案。但是关于“然而你会牺牲sequelize的功能性。”你的意思是我将无法执行一些日期指定的查询吗? - f1nn
Sequelize将对象映射到表中。该映射提供了一个面向对象的数据库接口。如果这些值没有设置,Sequelize将无法检查对象是否已更新。您将不得不重写该逻辑。 - cs_alumnus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接