我正在做
console.log(process.env.TZ);
console.log(new Date());
它输出
Europe/Amsterdam
2018-09-02T08:07:03.842Z
但是当前时间是10:07而不是08:07。
实际的问题是,当我将模型保存到数据库时,它会以某种方式转换为UTC,这不是我想要的。就像order.delivery_date = 2018-08-06 10:00:00; order.save()。当我查看数据库时,它说08:00:00。如何防止这种情况发生?
我正在使用Loopback 3和MySQL。
答案 0 :(得分:18)
它输出
Europe/Amsterdam 2018-09-02T08:07:03.842Z
但是当前时间是10:07而不是08:07。
字符串上的Z
表示时间是UTC,而不是本地时间。当您将字符串传递给字符串(来自toUTCString
时),这只是Node.js控制台输出的字符串。 JavaScript Date
对象在本地时间工作,但也具有访问UTC时间的功能(getUTCHours
,getUTCMinutes
等); toUTCString
是其中之一。
您可以在Date
对象(getHours
,getMinutes
等)上使用各种本地时间功能,并从中获取本地时间信息。 (例如,toString
可能会给您一个本地时间字符串。)
答案 1 :(得分:4)
我没有您设置的完整图片,但是是的,保存日期时,环回确实会从本地时间转换为UTC。如果您查看mysql连接器,则会发现以下函数,该函数从给定日期的UTC值构建datetime
字符串:
function dateToMysql(val) {
return val.getUTCFullYear() + '-' +
fillZeros(val.getUTCMonth() + 1) + '-' +
fillZeros(val.getUTCDate()) + ' ' +
fillZeros(val.getUTCHours()) + ':' +
fillZeros(val.getUTCMinutes()) + ':' +
fillZeros(val.getUTCSeconds());
function fillZeros(v) {
return v < 10 ? '0' + v : v;
}
}
但是,它应该将日期恢复为加载时的本地时间,因为它会从存储的字符串中初始化javascript Date
对象,该对象将转换为本地时间:
val = new Date(val.toString().replace(/GMT.*$/, 'GMT'));
您最好的选择可能是使用operation hooks并在数据流入/流出模型时对其进行操作。例如,您可以根据需要设置日期的格式,例如从数据存储中加载数据的时间:
Order.observe("loaded", (ctx, next) => {
if (ctx.data) {
ctx.data.delivery_date_formatted = tzFormat(ctx.data.delivery_date);
}
next();
});
您还可以从另一个方向进行处理,并处理要保留的数据。您无法真正阻止回送将日期存储为UTC,但是您可以添加或删除时区偏移,因此一旦被回送连接器剥离了时区偏移量,它将以您的本地时间保存字符串(很黑,我不会推荐)。示例:
Order.observe("before save", (ctx, next) => {
if (ctx.instance) {
ctx.instance.delivery_date = new Date(
Date.UTC(
ctx.instance.delivery_date.getFullYear(),
ctx.instance.delivery_date.getMonth(),
ctx.instance.delivery_date.getDate(),
ctx.instance.delivery_date.getHours(),
ctx.instance.delivery_date.getMinutes(),
ctx.instance.delivery_date.getSeconds()
)
);
}
next();
});
答案 2 :(得分:0)
回答标题问题:
new Date()
将返回UTC时间值,该值在字符串末尾具有Z
时区指示符和时区值(在您的情况下为2
)。
回答有关数据库save()
的问题:
这取决于您的数据访问层和数据列类型。
可能有两种主要方法:
因此您的save()
可以正确地使用该方法,您应该只添加一个本地时间转换器(通常最好的方法是将其添加到前端)
因此,您应该在写/读时建立转换器,或者更改列的类型,因此它不应该使用UTC格式(一种简单的方法,但是不巧的方法是将其存储为字符串值),例如
如果您选择转换器的方式,我建议您使用moment.js(用于前端或后端)。当您需要进行任何时间操作时,它可以节省时间,但可能会增加开销。
您也可以手动进行制作(例如,以减小捆绑包尺寸),也可以使用this答案中的方法:
const options = {
timeZone: "America/New_York",
year: 'numeric', month: 'numeric', day: 'numeric',
hour: 'numeric', minute: 'numeric', second: 'numeric'
};
const formatter = new Intl.DateTimeFormat([], options);
const UTCTime = "2017-09-03T02:00:00Z";
const localTime = formatter.format(new Date(UTCTime));
const currentTime = formatter.format(new Date());
console.log(currentTime, localTime);