提问人:Aušrys Mikoliūnas 提问时间:11/9/2023 更新时间:11/9/2023 访问量:35
与本地主机和生产环境上的请求日期不同
Different dates from the request on localhost and production
问:
我正在从前端到后端发送信息,信息的一个关键部分是发送日期。我正在使用 React 和 Node.js Express。当我在自己的机器上工作时,它工作正常,我获取日期,使其处于发送它的用户的正确时区,并将其保存到数据库中。当我将我的项目投入生产时:后端 - ''Cyclic.sh“,前端 - Vercel,我在后端收到的日期格式错误。
对于日期操作,我使用了 Luxon。
以下是我收到它们的方式:
const { prods, createdAt, ...rest } = req.body;
if (prods.length < 1)
return res.status(400).json({ error: "At least one product is required" });
const luxonDate = DateTime.fromISO(createdAt);
console.log(luxonDate);
if (luxonDate.invalidExplanation)
return res.status(400).json({ error: luxonDate.invalidExplanation });
const normalizedDate = luxonDate.toISO();
以下是我发送它们的方式:
const handleSaveMeal = () => {
const currentDate = new Date();
postMealWithProducts.mutate({
...mealInfo,
prods: mealProducts,
title: selectedMealType,
isPortion: isPortion,
createdAt: currentDate,
});
无论是在本地机器上还是在生产环境中,如果我尝试在发送之前记录日期,则显示相同的格式(本地时间)。但是在生产中,当我收到它时,它比我的时间晚了 2 小时,即使在 localhost 上我收到了我的时间日期。
造成这种现象的原因可能是什么?
当我在后端记录日期时,我得到的是: 本地主机 - 标准化 2023-11-08T19:58:24.323+02:
00
生产 - 标准化 2023-11-08T18:01:18.358+00:00
答:
它不是比你的时间晚两个小时,只是它偏移了两个小时,因为生产环境使用 UTC 作为其本地时区。这是最佳做法,因为它会提醒您注意此类问题。
使用 DateTime.fromISO
分析字符串时,默认时区将是计算机的本地时区。如果您想要不同的时区,则可以通过在选项中提供 来覆盖该行为 - 或者您可以在生成的对象上使用。zone
setZone
DateTime
但是,我怀疑您在这里想要的是保留原始输入字符串中提供的本地时间和偏移量。为此,请在解析时设置:setZone: true
const luxonDate = DateTime.fromISO(createdAt, { setZone: true });
当然,这假定字符串实际上包含偏移量,例如您显示的示例中。不过很难说,因为我不知道您的函数在将对象转换为字符串方面做了什么。如果它发送偏移量,那么你应该没问题。但是,如果它只是发送 UTC 时间 (offset: ),则服务器无法保留本地时间和偏移量,因为您不是从客户端发送的。createdAt
+02:00
postMealWithProducts.mutate
createdDate
Date
Z
评论
Z
JSON.stringify(new Date())
+02:00
"Europe/Vilnius"
问题是,当我在前端记录日期时,我在 Chrome 中的控制台向我显示了带有偏移量的完整日期,这让我认为日期将以正常格式发送。但是,在评论中,有人向我解释说,它只发送日期而没有偏移量。当我复制控制台输出并粘贴到这里时,可以看到它显示了没有偏移量的日期(也许是 Chrome 添加的偏移量)。所以在前端,我添加了偏移量:
const currentDate = new Date();
const userTimezone = currentDate.getTimezoneOffset();
postMealWithProducts.mutate({
...mealInfo,
prods: mealProducts,
title: selectedMealType,
isPortion: isPortion,
createdAt: currentDate,
userTimezone: userTimezone,
});
然后在后端,我编辑代码,以便 Luxon 添加偏移量。偏移量乘以负 1,因为函数 getTimezoneOffset() 返回提供的差异日期和以分钟为单位的 utc,如果时区在前面,则为负数,如果时区在后面,则为正数。反之亦然,前时区为正,后时区为负,这就是我将其乘以 -1 的原因。
const { prods, createdAt, userTimezone, ...rest } = req.body;
if (prods.length < 1)
return res.status(400).json({ error: "At least one product is required" });
const luxonDate = DateTime.fromISO(createdAt, { zone: userTimezone * -1 });
if (luxonDate.invalidExplanation)
return res.status(400).json({ error: luxonDate.invalidExplanation });
const normalizedDate = luxonDate.toISO();
评论