如何使用原生Date对象或date-fns修复iOS端Invalid date问题
问题根因
- iOS 端全量浏览器都使用 WebKit 内核,该内核对
Date构造函数的入参格式校验极严格,无法直接识别后端返回的YYYY-MM-DD HH:mm:ss格式(日期和时间用空格分隔)的字符串,直接传入会得到Invalid Date对象,这是第一次实现返回错误的核心原因。 - 第二次引入 date-fns 的
intlFormat后页面崩溃,是因为把iOS环境下构造失败的Invalid Date对象传入了格式化方法,触发了内部逻辑异常,和intlFormat本身的能力无关。
可行解决方案
两种方案都可以满足「根据浏览器区域设置自适应输出对应格式,英文环境下输出Nov 24, 2021样式」的要求,任选其一即可。
方案1:原生JS实现,无额外依赖
不需要引入第三方库,先做日期字符串的兼容处理,再调用原生本地化格式化方法即可:
const getDate = (dateStr) => { // 兼容WebKit内核:替换分隔符为标准可解析格式 const parseableStr = dateStr.replace(/-/g, '/').replace(' ', 'T'); const targetDate = new Date(parseableStr); // 兜底获取用户区域设置 const userLocale = navigator.languages?.length ? navigator.languages[0] : (navigator.language || 'en-US'); return targetDate.toLocaleDateString(userLocale, { month: 'short', day: 'numeric', year: 'numeric' }); };
方案2:date-fns 正确实现
如果项目中已经引入date-fns,只需要在格式化前先把日期字符串处理成WebKit可识别的格式,构造合法Date对象后再传入即可:
import { intlFormat } from 'date-fns'; const getDate = (dateStr) => { // 先做兼容处理,生成合法Date实例 const parseableStr = dateStr.replace(/-/g, '/').replace(' ', 'T'); const targetDate = new Date(parseableStr); const userLocale = navigator.languages?.length ? navigator.languages[0] : (navigator.language || 'en-US'); return intlFormat( targetDate, { month: 'short', day: 'numeric', year: 'numeric' }, { locale: userLocale } ); };
注意:iOS 端所有第三方浏览器(包括Chrome、Edge、Firefox)都被苹果强制要求使用WebKit内核,不存在「Chrome for iOS 能识别非标准日期格式」的情况,所有跨端日期处理逻辑都必须先做格式兼容再传入Date构造函数。
内容的提问来源于stack exchange,提问作者Рома Прокопец
相关产品推荐
相关产品推荐

