Bookshelf.js/Knex.js 对 UTC DATETIME 列太“有用”

Posted

技术标签:

【中文标题】Bookshelf.js/Knex.js 对 UTC DATETIME 列太“有用”【英文标题】:Bookshelf.js/Knex.js is too "helpful" with UTC DATETIME columns 【发布时间】:2014-09-22 14:50:32 【问题描述】:

我有一个 mysql 表,该表有一个名为 datetime_utcDATETIME 列。如您所料,它是 UTC 的日期和时间。在我的 Bookshelf 模型中,我定义了一个虚拟 getter,它使用 Moment.js 将其转换为 ISO 8601 字符串格式。我的模型看起来像这样:

bookshelf.plugin('virtuals');

exports.MyModel = bookshelf.Model.extend(
    tableName : 'my_table',
    idAttribute : 'id',
    virtuals : 
        datetime_iso : 
            get : function () 
                return moment.utc(this.get('datetime_utc')).format();
            
        
    
);

问题是,当 Bookshelf(或为其提供支持的底层 Knex)看到 DATETIME 列时,它会将值包装在 new Date(...) 中,然后再将其提供给我的代码。由于日期的值是 UTC,但 Date 构造函数假定该值位于服务器的本地非 UTC 时区,我最终得到一个 Date 对象,该对象在错误的时区具有正确的日期。一旦 Moment 在此日期开始工作,所有值都会偏离固定的小时数。

我通过查找 Date 对象并将日期组件直接分解到 Moment 构造函数中来解决此问题。但感觉很恶心:

get : function () 
    var dt = this.get('datetime_utc');

    if (dt instanceof Date) 
        dt = [
            dt.getFullYear(), dt.getMonth(), dt.getDate(),
            dt.getHours(), dt.getMinutes(), dt.getSeconds()
        ];
    

    return moment.utc(dt).format();

是否有更简洁的方法可以从 Bookshelf 获取未包装的 YYYY-MM-DD HH:MM:SS 字符串值,或者使用速记法从时区忽略/修改为 UTC 的 Date 创建新的 Moment 对象?

【问题讨论】:

嗨,您为此提出过问题吗? @Zhianc 目前我还没有。我仍然不确定这是一个合法的错误还是我滥用了这个库。 我实际上并没有找到符合您所说的代码。 【参考方案1】:

事实证明,这不是由 Knex 或 Bookshelf 引起的,而是由底层的 node-mysql 库引起的。有一个名为 timezone 的连接属性将被附加到每个 DATETIMEDATETIMESTAMPNEWDATE 值,然后再将其解析为 Date 对象。

Knex 将在初始化时将此属性传递给 node-mysql:

require('knex')(
    "client": "mysql",
    "connection": 
        "host": "...",
        "user": "...",
        "password": "...",
        "database": "...",
        "timezone": "UTC"    <-- This is the culprit
    
);

【讨论】:

但是插入的时候呢?我看到“where end_stamp >= '2016-01-31 16:12:58.615'”是根据当前时区而不是 UTC 进行转换的...有什么想法吗? 为了解决问题,是加了"timezone": "UTC"还是去掉了? 我遇到了同样的问题。为了解决它,你添加 "timezone": "UTC"...

以上是关于Bookshelf.js/Knex.js 对 UTC DATETIME 列太“有用”的主要内容,如果未能解决你的问题,请参考以下文章

springboot使用undertow服务器UT005023出错

工作多年后我更了解了UT的重要性

UT常用注解

在软件测试中UT,IT,ST,UAT分别是啥意思?

MySQL 源码中的 ut_a ut_ad

在软件测试中UT,IT,ST,UAT分别是啥意思