JavaScript中如何用正则仅替换ISO时间字符串中T后的前两个字符
问题解决
1. 直接修复正则问题
你当前用的/[T-:]/正则会匹配字符串中第一个出现的T、-或:字符,自然无法实现只替换T后前两位数字的需求。可以用正向零宽断言匹配T后面紧跟的两位数字,正确写法如下:
// 3. 替换T后的前两位小时数字,注意给个位数小时补前导0 let localTime = date.toISOString().replace(/(?<=T)\d{2}/, String(localHour).padStart(2, '0'));
如果需要兼容不支持零宽断言的旧环境,可以用分组匹配的写法:
let localTime = date.toISOString().replace(/(T)\d{2}/, `$1${String(localHour).padStart(2, '0')}`);
2. 现有实现的隐藏隐患
除了正则外,你的方案还有两个很容易踩的坑:
- 时区计算逻辑仅在西时区场景下刚好正确:
getTimezoneOffset()返回的是「本地时间比UTC时间少的分钟数」,比如东8区会返回-480,除以60得到-8,用UTC小时减offset会得到20 - (-8) = 28的错误结果 - 没有处理跨天/跨月/跨年场景:比如UTC 11月8日23点加8小时就是11月9日7点,只替换小时数字会导致日期完全错误
3. 更稳妥的实现方案
完全不需要手动计算时区、处理日期进位,直接用Date自带的本地时间取值方法拼接即可:
let date = new Date('2021-11-08T20:31:23.746Z'); function getLocalISOString(date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); const seconds = String(date.getSeconds()).padStart(2, '0'); const ms = String(date.getMilliseconds()).padStart(3, '0'); return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${ms}Z`; } console.log(getLocalISOString(date)); // 东8区环境输出:2021-11-09T04:31:23.746Z // 西7区环境输出:2021-11-08T13:31:23.746Z
内容的提问来源于stack exchange,提问作者Tyler Morales
相关产品推荐
相关产品推荐

