Node.js+EJS沙龙预约系统部署后IST时区下已过时段禁用逻辑失效问题
Node.js+EJS沙龙预约系统部署后IST时区下已过时段禁用逻辑失效问题
我之前也踩过Vercel部署后时区偏移的坑,你的核心问题其实出在服务器端解析时段时间的方式上——虽然你用了date-fns-tz转IST,但创建时段时间的第一步就错了,导致后续传递给前端的时间戳完全不符合预期。
问题根源分析
Vercel的服务器默认运行在UTC时区,你原来创建时段时间的代码:
let inputDate = new Date(`${date}T${allTime[j]}:00`); inputDateIST = dateFnsTz.toZonedTime(inputDate, timeZone);
这里的new Date(${date}T${allTime[j]}:00)在UTC服务器上会被解析为UTC时区的该时间点,而非你想要的IST时区。比如你想解析IST的2024-05-20 09:00,服务器会把它当成UTC的2024-05-20 09:00,转成IST后就变成了14:30,直接导致前端比较时判断错误。
另外,你获取当前IST时间的方式可以更直接,避免多余的转换步骤。
修复后的后端代码
我调整了你的代码,主要解决两个关键问题:
- 用
date-fns-tz.parse直接将日期时间字符串解析为IST时区的时间,跳过错误的UTC解析步骤 - 用
nowInTimeZone直接获取当前IST时间的时间戳,更可靠
let { date } = req.params; console.log(date); const services = await Service.find({}); const orders = await Order.find({ date: date }); let bookedTime = []; if (orders.length) { bookedTime = orders.map((ord) => ord.time); } const allTime = ["09:00", "10:00", "11:00", "12:00", "14:00", "15:00", "16:00", "17:00", "19:00", "20:00"]; let inputDateTime = []; const timeZone = 'Asia/Kolkata'; // 直接获取当前IST时间的时间戳,替代先取UTC再转换的方式 const currDate = dateFnsTz.nowInTimeZone(timeZone); for (let j = 0; j < allTime.length; j++) { // 关键修复:直接解析为IST时区的时间点,而非先转UTC const inputDateIST = dateFnsTz.parse( `${date}T${allTime[j]}:00`, "yyyy-MM-dd'T'HH:mm:ss", new Date(), { timeZone: timeZone } ); inputDateTime[j] = inputDateIST.getTime(); } // 部署后可以在Vercel日志里查看这些值,验证时间是否正确 console.log('Current IST timestamp:', currDate); console.log('IST time slots timestamps:', inputDateTime); res.render("orders/newTwo.ejs", { services, bookedTime, date, allTime, inputDateTime, currDate });
额外验证建议
- 部署后去Vercel的函数日志里查看打印的
currDate和inputDateTime,确认时间戳对应的是正确的IST时间(比如IST 09:00的时间戳应该比UTC 09:00早5.5小时) - 前端也可以在控制台打印这两个值,和后端日志对比,确保没有传输过程中的偏差
为什么本地正常?
因为你的本地机器设置的是IST时区,new Date(${date}T${allTime[j]}:00)会直接解析为IST时间,所以后续转换没问题。但部署到UTC时区的服务器后,这个解析逻辑就出错了,这是跨时区部署的常见坑。
备注:内容来源于stack exchange,提问作者Harsh
相关产品推荐
相关产品推荐

