为何显示无效日期?如何获取伦敦当前时间?(moment.tz不可用)
问题解答
1. 无效日期的原因
你的代码里导致无效日期的核心问题有两个:
- 字符串解析兼容性问题:
new Date(new Date().toLocaleString('en-GB', { timeZone: 'Europe/London' }))依赖浏览器对本地化日期字符串的解析能力。toLocaleString返回英式格式(如15/01/2023, 05:20:09),这类非ISO标准格式的字符串在不同浏览器中解析逻辑不一致,极易出现解析失败,返回Invalid Date。 - 丢失日期维度的错误处理:你通过
moment(prevRefreshTime).format('HH:mm:ss')仅提取时分秒,丢弃了日期信息。若历史时间与当前时间不在同一天,这种处理会让startTime和endTime被默认当成当天时间,不仅计算结果完全错误,还可能触发moment的隐式日期解析异常。
2. 获取伦敦当前时间的正确方式
无法使用 moment.tz() 时,推荐用原生 Intl.DateTimeFormat 获取伦敦时区的时间组件,或直接将当前时间转换为伦敦时区的标准格式后处理。更关键的是,计算时间差必须保留完整的日期时间信息,通过时间戳计算才能保证准确性。
修正后的代码(满足伦敦时间差计算需求)
// 1. 解析已知的伦敦历史时间为UTC时间戳 const prevRefreshTime = "2023-01-15 05:20:09"; // 伦敦时间 // 拆分历史时间的年、月、日、时、分、秒组件 const [year, month, day, hour, minute, second] = prevRefreshTime.split(/[- :]/); // 构造对应伦敦时间的UTC日期对象(规避夏令时影响) const prevLondonDate = new Date(Date.UTC(year, month - 1, day, hour, minute, second)); const prevTimestamp = prevLondonDate.getTime(); // 2. 获取当前伦敦时间的UTC时间戳 const londonFormatter = new Intl.DateTimeFormat('en-GB', { timeZone: 'Europe/London', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); // 提取当前伦敦时间的各组件 const nowLondonParts = londonFormatter.formatToParts(new Date()).reduce((acc, part) => { acc[part.type] = part.value; return acc; }, {}); // 构造当前伦敦时间的UTC日期对象 const nowLondonDate = new Date(Date.UTC( nowLondonParts.year, parseInt(nowLondonParts.month) - 1, nowLondonParts.day, nowLondonParts.hour, nowLondonParts.minute, nowLondonParts.second )); const nowTimestamp = nowLondonDate.getTime(); // 3. 计算分钟差值 const minutesDiff = Math.abs((nowTimestamp - prevTimestamp) / (1000 * 60)); console.log(minutesDiff);
代码说明
- 对于已知伦敦历史时间,直接拆分字符串获取时间组件,用
Date.UTC构造UTC时间对象,避免夏令时带来的时区转换误差。 - 对于当前伦敦时间,通过
Intl.DateTimeFormat.formatToParts精准提取时区对应的时间组件,再构造UTC时间对象。 - 基于时间戳差值计算分钟数,彻底规避字符串解析的兼容性问题,同时保证跨天、跨夏令时场景下计算的准确性。
内容的提问来源于stack exchange,提问作者Motalib Hossain
相关产品推荐
相关产品推荐

