使用 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 中未正确保存日期(比实际日期少一天)的主要内容,如果未能解决你的问题,请参考以下文章