使用 NodeJS 在 mysql 中未正确保存日期(比实际日期少一天)

Posted

技术标签:

【中文标题】使用 NodeJS 在 mysql 中未正确保存日期(比实际日期少一天)【英文标题】:Date is not saving properly in mysql with NodeJS (one day lesser than real date) 【发布时间】:2016-11-29 16:48:15 【问题描述】:

我使用 Node.JS 和 ExpressJS 创建了休息服务器。数据库是 mysql。 我从前端传递日期如下。

2016-7-26

当我访问数据库时,它是这样保存的。如下:

2016-07-26 00:00:00

因为mysql的日期格式是时间戳。当我从 REST 规则中获取结果时,我会得到这样的日期。

“2016-07-25T18:30:00.000Z”

我保存了 26。但在这里我得到了 25。这是什么原因?时区 ?请告诉我如何解决此问题。

【问题讨论】:

看起来像时区问题。 这是一个时区问题。将数据库设置为 UTC,除非您想不断地与之抗争。仅在您的应用程序代码中使用时区,即使这样也仅基于用户偏好。 您的意思是将数据库时区更改为 UTC ?做过某事。不工作 @tadman 嘿,我做到了。还是不行。你能帮帮我吗 "MySQL 将 TIMESTAMP 值从当前时区转换为 UTC 进行存储,并从 UTC 转换回当前时区进行检索。(对于其他类型,如 DATETIME,不会发生这种情况。)" @ 987654321@也许这可能是个问题 【参考方案1】:

这是因为节点将日期转换为 ISOString 并且日期为 GMT。 从数据库中查询数据后使用<your date>.toLocaleString();

例子:

connection.query(yourDbQuery, function(err, result) 
    if(result)   
        var date = result.date.toLocaleString(); 
    
);

您还可以安装对日期非常有用的 npm moment。

安装,使用

npm install moment

并使用以下代码:

const moment = require('moment');
let date = moment(result.date).format('DD/MM/YYYY');

【讨论】:

result.date = moment(new Date()).format('DD/MM/YYYY'); -> 这是什么代码? 我已经编辑了上面的内容。结果是 db 查询的结果。 result.date 假设是您从数据库中获取的日期,您也可以使用此行代替 result.date.toLocaleString(); chanu1993@gmail.com -> 给我发电子邮件【参考方案2】:

在我的例子中, .toLocalString() 返回相同的 iSOString 格式。所以,我使用自己的 coaded 函数将 iSOString 时间转换为任何格式(在本例中为 UTC 格式)。

例如:2018-02-09T12:18:23.000Z => 2018-02-09 12:18:23

这是我获取 UTC 日期格式的方式:

var date = date_formate(new Date(result[0].date), "yyyy-MM-dd HH:mm:ss");

在您的代码中包含以下自定义函数。

function date_formate (date, format, utc) 
    var MMMM = ["\x00", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
    var MMM = ["\x01", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    var dddd = ["\x02", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
    var ddd = ["\x03", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

    var y = utc ? date.getUTCFullYear() : date.getFullYear();
    format = format.replace(/(^|[^\\])yyyy+/g, "$1" + y);
    format = format.replace(/(^|[^\\])yy/g, "$1" + y.toString().substr(2, 2));
    format = format.replace(/(^|[^\\])y/g, "$1" + y);

    var M = (utc ? date.getUTCMonth() : date.getMonth()) + 1;
    format = format.replace(/(^|[^\\])MMMM+/g, "$1" + MMMM[0]);
    format = format.replace(/(^|[^\\])MMM/g, "$1" + MMM[0]);
    format = format.replace(/(^|[^\\])MM/g, "$1" + this.pad(M, 2));
    format = format.replace(/(^|[^\\])M/g, "$1" + M);

    var d = utc ? date.getUTCDate() : date.getDate();
    format = format.replace(/(^|[^\\])dddd+/g, "$1" + dddd[0]);
    format = format.replace(/(^|[^\\])ddd/g, "$1" + ddd[0]);
    format = format.replace(/(^|[^\\])dd/g, "$1" + this.pad(d, 2));
    format = format.replace(/(^|[^\\])d/g, "$1" + d);

    var H = utc ? date.getUTCHours() : date.getHours();
    format = format.replace(/(^|[^\\])HH+/g, "$1" + this.pad(H, 2));
    format = format.replace(/(^|[^\\])H/g, "$1" + H);

    var h = H > 12 ? H - 12 : H == 0 ? 12 : H;
    format = format.replace(/(^|[^\\])hh+/g, "$1" + this.pad(h, 2));
    format = format.replace(/(^|[^\\])h/g, "$1" + h);

    var m = utc ? date.getUTCMinutes() : date.getMinutes();
    format = format.replace(/(^|[^\\])mm+/g, "$1" + this.pad(m, 2));
    format = format.replace(/(^|[^\\])m/g, "$1" + m);

    var s = utc ? date.getUTCSeconds() : date.getSeconds();
    format = format.replace(/(^|[^\\])ss+/g, "$1" + this.pad(s, 2));
    format = format.replace(/(^|[^\\])s/g, "$1" + s);

    var f = utc ? date.getUTCMilliseconds() : date.getMilliseconds();
    format = format.replace(/(^|[^\\])fff+/g, "$1" + this.pad(f, 3));
    f = Math.round(f / 10);
    format = format.replace(/(^|[^\\])ff/g, "$1" + this.pad(f, 2));
    f = Math.round(f / 10);
    format = format.replace(/(^|[^\\])f/g, "$1" + f);

    var T = H < 12 ? "AM" : "PM";
    format = format.replace(/(^|[^\\])TT+/g, "$1" + T);
    format = format.replace(/(^|[^\\])T/g, "$1" + T.charAt(0));

    var t = T.toLowerCase();
    format = format.replace(/(^|[^\\])tt+/g, "$1" + t);
    format = format.replace(/(^|[^\\])t/g, "$1" + t.charAt(0));

    var tz = -date.getTimezoneOffset();
    var K = utc || !tz ? "Z" : tz > 0 ? "+" : "-";
    if (!utc) 
        tz = Math.abs(tz);
        var tzHrs = Math.floor(tz / 60);
        var tzMin = tz % 60;
        K += this.pad(tzHrs, 2) + ":" + this.pad(tzMin, 2);
    
    format = format.replace(/(^|[^\\])K/g, "$1" + K);

    var day = (utc ? date.getUTCDay() : date.getDay()) + 1;
    format = format.replace(new RegExp(dddd[0], "g"), dddd[day]);
    format = format.replace(new RegExp(ddd[0], "g"), ddd[day]);

    format = format.replace(new RegExp(MMMM[0], "g"), MMMM[M]);
    format = format.replace(new RegExp(MMM[0], "g"), MMM[M]);

    format = format.replace(/\\(.)/g, "$1");

    return format;

【讨论】:

【参考方案3】:

这是因为 JS 将根据客户端时区更新任何日期。 因此,我使用下面的 npm 库来更新来自 API 和来自 SQL 的任何 Date 对象,如下所示:

import  framework, libs  from 'saffroncodejs';//For react
import  framework, libs  from 'saffroncodejs-pure';//For NodeJS

...
//result.data.result = any:1,item:2,haveDates:any:2,date:"2016-07-25T18:30:00.000Z"

libs.JSFunctions.correctDates(result.data.result);

//>> result.data.result = any:1,item:2,haveDates:any:2,date:"2016-07-26T00:00:00.000Z"

https://www.npmjs.com/package/saffroncodejs

在那里你可以找到纯 js 脚本: https://github.com/SaffronCode/SaffronCodeJS/blob/master/src/libs/JSFunctions.ts

【讨论】:

【参考方案4】:

我遇到了类似的问题,但是在从 db 获取数据时。日期提前了一天。 所以,要解决这个问题。我在查询本身中格式化了日期。

DATE_FORMAT(date_time, "%Y-%m-%d")

例如。 :- 问题:

查询: 从 tbl 中选择百分比,DATE(date_time) 作为日期;

输出:

[
   percentage: 3,
   date: "2019-06-11T18:30:00.000Z"
 ]

解决方案:

查询: 从 tbl 中选择百分比,DATE_FORMAT(date_time, "%Y-%m-%d") 作为日期; 输出:

[
   percentage: 3,
   date: "2019-06-12"
]

【讨论】:

【参考方案5】:

就我而言,原始日期:2020 年 1 月 1 日,数据库输出:2019 年 12 月 31 日。 这个简单的技巧奏效了

var date = 'result from mysql';
date = date.setDate(date.getDate()+1);
console.log(date); // 1/1/2020

【讨论】:

【参考方案6】:

通过将连接选项设置为

日期字符串:['DATE','DATETIME']

为我工作!

【讨论】:

【参考方案7】:

问题不在于保存数据或 SQL 本身;因为如果您直接在 DB 上运行查询,它将显示保存的正确值。

您可以在每个查询中解决此问题,方法是在 SQL 端添加一些答案所建议的日期;但这不是一个正确的解决方案。

另一种选择是在 node.js 中通过添加值来解决此问题;这也不是正确的方法。

据我了解,在初始化 mysql 连接时设置时区的正确方法。 

var connection = mysql.createConnection(
    host: '192.99.99.99',
    user: 'user',
    password: 'password',
    database: 'mydb',
    timezone: 'utc' //<-- here
  );

【讨论】:

以上是关于使用 NodeJS 在 mysql 中未正确保存日期(比实际日期少一天)的主要内容,如果未能解决你的问题,请参考以下文章

使用 PDFBOX 生成的 PDF 中未正确显示已保存的文本字段值

在 MYSQL 中未正确识别不同的术语

NodeJS - 无法正确创建递归 MySQL 请求

无法读取 Node JS 中未定义的属性“名称”

mysql中未读消息的数据库设计?

Nodejs/Express 保存从 web 客户端选择头像并直接保存到 MySQL 数据库