如何获取应用所在服务器时区并实现跨时区时间匹配触发定时任务
问题原因
你的代码问题出在new Date().toLocaleTimeString()默认使用运行环境的本地时区,Heroku服务器默认时区为UTC,和你需要的美国东部时间不一致,因此时间匹配条件永远无法触发。
解决方案
方案1:代码中固定时区(推荐,不受部署环境影响)
直接在调用toLocaleTimeString时指定时区为美国东部时区(IANA时区标识为America/New_York),同时固定时间输出格式,避免不同环境的格式差异导致匹配失败。
const sendMessage = require('./sms-api.js'); const send = () =>{ // 可选:添加发送标记位,避免同一天重复触发 let morningSent = false, eveningSent = false; // 每日0点重置发送标记 setInterval(() => { const now = new Date(); if (now.getHours() === 0 && now.getMinutes() === 0) { morningSent = false; eveningSent = false; } }, 60000) setInterval(()=>{ // 固定获取美国东部时间,同时统一输出格式 var x = new Date().toLocaleTimeString('en-US', { timeZone: 'America/New_York', hour12: true, hour: '2-digit', minute: '2-digit', second: '2-digit' }); console.log(x); if(x === '11:00:10 AM' && !morningSent) { console.log('match'); morningSent = true; return sendMessage('6178032176', 'Good Morning'); } // 注意:格式化后小时会补前导零,匹配条件要写09而不是9 else if(x === '09:50:20 PM' && !eveningSent) { console.log('match'); eveningSent = true; sendMessage('6178032176', 'Good Evening'); } },1000) } send();
该方案会自动处理美国东部的夏令时切换,无需手动调整时间偏移。
方案2:修改Heroku环境时区
如果不想调整代码,可以直接修改Heroku应用的全局时区配置:
- 进入Heroku应用的Settings页面,找到Config Vars选项
- 新增变量,键为
TZ,值为America/New_York,保存后重启应用即可
修改后原有代码无需调整,运行时会默认使用美国东部时间。
优化建议
每秒轮询的逻辑存在跳秒漏触发的可能,建议可以把匹配逻辑改成判断时间大于等于目标时间,搭配发送标记位使用,稳定性更高。
内容的提问来源于stack exchange,提问作者Alex Antoine
相关产品推荐
相关产品推荐

