节点脚本查询时数据库中的日期不匹配

mir*_*n80 3 mysql node.js

我有一个节点脚本,它创建一个日期对象,将其转换为字符串,控制台将日期和日期记录为字符串,然后将日期字符串插入 DATE、DATETIME 和 TIMESTAMP 类型的 sql 数据库字段中。数据库位于 Windows 10 的 XAMPP 中,当地时间为下午 2 点。

\n\n
(async () => {\n    const fs = require("fs");\n    const mysql = require(\'mysql2/promise\');\n\n    let date = new Date();\n    let dateString = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();\n    console.log("date: ", date);\n    console.log("datestring: ", dateString);\n\n    const connection = await mysql.createConnection(JSON.parse(fs.readFileSync("../test/databaseLogin.json")));\n    await connection.execute("INSERT INTO dates VALUES (?, ?, ?, ?)", [1, dateString, dateString, dateString]);\n\n    const selectResults = await connection.execute("SELECT * FROM `dates` WHERE mainKey = ?", [1]);\n    console.log("DB field of type DATE: ", selectResults[0][0].date);\n    console.log("DB field of type DATETIME: ", selectResults[0][0].datetime);\n    console.log("DB field of type TIMESTAMP: ", selectResults[0][0].timestamp);\n    connection.close();\n})();\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我使用mysql2 npm从节点进程查询数据库,我会得到不同的结果,即 24 号而不是 25 号。\n完整的控制台输出:

\n\n
date:  2019-12-25T13:19:01.204Z\ndatestring:  2019-12-25\nDB field of type DATE:  2019-12-24T23:00:00.000Z\nDB field of type DATETIME:  2019-12-24T23:00:00.000Z\nDB field of type TIMESTAMP:  2019-12-24T23:00:00.000Z\n
Run Code Online (Sandbox Code Playgroud)\n\n

我不明白为什么会有差异。也许存在某种本地化问题?但该日期是在读取的同一区域设置中创建的。

\n\n

数据的数据库表示:

\n\n
MariaDB [test]> SELECT *  FROM dates;\n+---------+------------+---------------------+---------------------+\n| mainKey | date       | datetime            | timestamp           |\n+---------+------------+---------------------+---------------------+\n|       1 | 2019-12-25 | 2019-12-25 00:00:00 | 2019-12-25 00:00:00 |\n+---------+------------+---------------------+---------------------+\n
Run Code Online (Sandbox Code Playgroud)\n\n
MariaDB [test]> describe dates;\n+-----------+-----------+------+-----+-------------------+-----------------------------+\n| Field     | Type      | Null | Key | Default           | Extra                       |\n+-----------+-----------+------+-----+-------------------+-----------------------------+\n| mainKey   | int(11)   | NO   | PRI | NULL              |                             |\n| date      | date      | NO   | PRI | NULL              |                             |\n| datetime  | datetime  | NO   |     | NULL              |                             |\n| timestamp | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |\n+-----------+-----------+------+-----+-------------------+-----------------------------+\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

MySQL将 TIMESTAMP 值从当前时区转换为 UTC 进行存储,并从 UTC 转换回当前时区进行检索。(对于其他类型(例如 DATETIME),不会发生这种情况。)默认情况下,每个连接的当前时区是服务器的时间。时区可以针对每个连接进行设置。只要时区设置保持不变,您就会得到与存储的相同的值。

\n
\n\n

我认为 mysql2 npm 不支持每个连接的时区配置。

\n

mir*_*n80 10

我在访问 mysql2 npm 模块的问题页面时找到了答案。

为了从数据库中“按原样”获取日期字符串,我必须添加以下连接设置:dateStrings: true。完整连接对象现在看起来像这样:

    const connection = await mysql.createConnection({
        host: 'localhost',
        user: 'root',
        password: 'pass',
        database: 'test',
        dateStrings: true
    });
Run Code Online (Sandbox Code Playgroud)

控制台输出:

date:  2019-12-25T20:38:09.522Z
datestring:  2019-12-25
DB field of type DATE:  2019-12-25
DB field of type DATETIME:  2019-12-25
DB field of type TIMESTAMP:  2019-12-25
Run Code Online (Sandbox Code Playgroud)