使用toISOString()格式化日期返回前一天值的问题排查
日期格式化问题:ISO日期转换后日期偏移一天
问题描述
JSON中提取的日期为2023-06-16T00:00:00,需要转换为dd/MM/yyyy格式展示,但调用自定义的formatDate方法后返回结果为15/06/2023,与预期的16/06/2023不符。要求必须保留toISOString()的使用逻辑,寻求解决办法。
自定义formatDate方法代码如下:
const formatDate = ( date: any, ignoreHours: boolean = false, formatDate: string = "dd/MM/yyyy" ) => { if (!date || date === "") return; if (ignoreHours) date = new Date(date).toISOString().split("T")[0]; const reg = /^\d+$/; const numbersOnlytest = reg.test(date); if (numbersOnlytest) { date = new Date(date).toISOString(); } return format(parseISO(date), formatDate); };
问题原因与解决方案
问题核心是时区偏移:当用new Date(date)解析2023-06-16T00:00:00时,浏览器会自动使用本地时区处理该日期。如果本地时区位于UTC以西,new Date(date)会将UTC时间转换为本地时间,导致日期往前偏移一天,后续调用toISOString()转回UTC格式时,就出现了日期不符的情况。
以下是保留toISOString()逻辑的修正方案:
修改后的代码
const formatDate = ( date: any, ignoreHours: boolean = false, formatDate: string = "dd/MM/yyyy" ) => { if (!date || date === "") return; let processedDate = date; // 处理数字时间戳转ISO字符串的场景 const reg = /^\d+$/; if (reg.test(processedDate)) { processedDate = new Date(Number(processedDate)).toISOString(); } // 忽略小时时,直接从原始ISO字符串截取日期段,避免时区转换 if (ignoreHours) { if (typeof processedDate === 'string' && processedDate.includes('T')) { processedDate = processedDate.split("T")[0]; } } // 用原始ISO字符串解析,规避时区偏移问题 return format(parseISO(processedDate), formatDate); };
关键调整点
- 调整处理顺序:先处理数字时间戳转ISO字符串的逻辑,再执行忽略小时的操作
- 跳过时区转换:忽略小时时,直接从原始ISO字符串中截取
YYYY-MM-DD部分,不通过new Date(date).toISOString()触发本地时区转换 - 增加类型校验:确保字符串类型判断后再执行截取操作,提升代码安全性
修改后,2023-06-16T00:00:00会被直接截取为2023-06-16,经parseISO解析后格式化,就能得到正确的16/06/2023结果。若你使用的format和parseISO来自date-fns这类日期库,该逻辑完全适配。
内容的提问来源于stack exchange,提问作者lol
相关产品推荐
相关产品推荐

