gpt4 book ai didi

node.js - 如何防止 Sequelize 将 Date 对象转换为本地时间

转载 作者:太空宇宙 更新时间:2023-11-03 21:52:17 25 4
gpt4 key购买 nike

我正在使用sequelize对于 Node 项目。它连接到 Postgres 数据库,其中包含一个带有 DATE 字段的表(与 TIMESTAMP WITH TIMEZONE 不同,DATE 没有时间数据)。

在代码中,我使用 javascript Date 对象对日期进行建模,该对象将时间存储为 UTC 午夜。当我使用该 Date 对象将记录插入到表中时,sequelize 显然首先将其转换为本地时间,因为记录总是晚 1 天。因此,如果我想将 2000-10-31 插入数据库,我最终会得到 2000-10-30。我现在处于 UTC-5。

如何告诉sequelize在插入数据库之前不要将日期转换为本地时间?

这是一些示例代码。我还创建了一个 repository如果您想自己运行它。

var Sequelize = require('sequelize');

const sequelize = new Sequelize('testdb', 'postgres', '???', {
host: 'localhost',
dialect: 'postgres'
});

TestTable = sequelize.define('date_test',
{
id: {
primaryKey: true,
type: Sequelize.INTEGER,
autoIncrement: true
},

someDate: {
field: 'some_date',
type: Sequelize.DATEONLY
}
},
{
timestamps: false,
freezeTableName: true
}
);

// midnight UTC on Halloween 🎃
var date = new Date(Date.UTC(2000, 9, 31));

// converts to local time resulting in 2000-10-30
TestTable.create({ someDate: date })
.then(function() {
// also apparently converts to local time resulting in 2000-10-30
return TestTable.create({ someDate: date.toUTCString() });
})
.then(function() {
// convert to string, definitely works but seems unnecessary
var strDate = date.getUTCFullYear() + '-' + pad2(date.getUTCMonth() + 1) + '-' + pad2(date.getUTCDate());
return TestTable.create({ someDate: strDate });
})
.then(function() {
// cerate a new local Date, also works but seems hacky
var newDate = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
return TestTable.create({ someDate: newDate });
})
.then(function() {
process.exit(0);
});


function pad2(n) {
if (n.length === 1) {
return '0' + n;
}

return n;
}

最佳答案

问题是日期被创建为 UTC 时间,但因为 DATEONLY不知道时区,它“按原样”(本地时间)格式化 Date 对象,格式为 YYYY-MM-DD (使用 moment.js - see here in source )。

对于DATEONLY你可以这样做:

var date = new Date(2000, 9, 31);

这将正确插入日期。

程序员很少这么说,但这一次你对时区的考虑太多了!

<小时/>

旧的错误答案

这取决于您如何检查该值,但 javascript 和 postgresql 会将其转换为您的本地时区以供显示。

Sequelize 对日期字段使用 TIMESTAMP WITH TIMEZONE 类型 ( source )。

postgresql docs它说:

For timestamp with time zone, the internally stored value is always in UTC (Universal Coordinated Time, traditionally known as Greenwich Mean Time, GMT). An input value that has an explicit time zone specified is converted to UTC using the appropriate offset for that time zone. If no time zone is stated in the input string, then it is assumed to be in the time zone indicated by the system's timezone parameter, and is converted to UTC using the offset for the timezone zone.

When a timestamp with time zone value is output, it is always converted from UTC to the current timezone zone, and displayed as local time in that zone. To see the time in another time zone, either change timezone or use the AT TIME ZONE construct (see Section 9.9.3).

如果您在 postgresql 中输出时间值,请尝试将其转换为 UTC。如果您使用 javascript 输出它,请尝试 date.toUTCString() .

你的黑客之所以能起作用,是因为它们实际上正在存储 2000-11-01 05:00但是当您检查该值时,它会转换为您本地的时区。

关于node.js - 如何防止 Sequelize 将 Date 对象转换为本地时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50546653/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com