Chrome 88在Android Galaxy Tab 2上调用toLocaleString后出现无效日期问题求助
问题原因分析
我之前处理过类似的兼容性问题,你遇到的核心问题是不同平台/浏览器对toLocaleString返回的日期字符串格式解析不一致——Galaxy Tab 2是比较老旧的安卓设备,它自带的浏览器(或你使用的Chrome版本偏旧)无法正确识别toLocaleString带时区参数后返回的日期格式,导致用这个字符串新建Date对象时抛出"invalid date"错误。
你的代码逻辑是先把当前日期转成悉尼时区的格式化字符串,再用这个字符串重新创建Date对象,这一步在旧设备上就卡壳了。
可行解决方案
方案1:直接使用格式化后的字符串(优先推荐,若仅需展示)
如果你的需求只是展示悉尼时区的日期时间,完全不需要把格式化后的字符串转回Date对象,直接用toLocaleString的结果即可:
var myDate = new Date(); // 直接获取悉尼时区的格式化字符串 var sydneyFormatted = myDate.toLocaleString('en-US', {timeZone: "Australia/Sydney"}); alert(sydneyFormatted); // 直接展示,不用再转Date
方案2:手动计算时区偏移来构建悉尼时间的Date对象
如果必须要得到对应悉尼时区的Date对象(或时间戳),可以通过时区偏移量手动计算:
var myDate = new Date(); // 悉尼时区是UTC+10,对应的偏移分钟数是-600(getTimezoneOffset返回本地与UTC的偏移,负数表示比UTC快) const SYDNEY_OFFSET_MINUTES = -600; // 计算本地时间与悉尼时间的差值,转换为毫秒 const timeDiff = (SYDNEY_OFFSET_MINUTES - myDate.getTimezoneOffset()) * 60 * 1000; // 得到悉尼时间的时间戳,再转成Date对象 const sydneyDate = new Date(myDate.getTime() + timeDiff); alert(sydneyDate.toLocaleString('en-US'));
方案3:用formatToParts拆分时间片段构建Date对象
利用Intl.DateTimeFormat的formatToParts方法,把日期拆分成年、月、日等独立片段,再用这些片段手动构建Date对象,避免解析字符串的问题:
var myDate = new Date(); const formatter = new Intl.DateTimeFormat('en-US', { timeZone: "Australia/Sydney", year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }); // 把格式化后的各个部分转成键值对 const dateParts = formatter.formatToParts(myDate).reduce((acc, part) => { acc[part.type] = part.value; return acc; }, {}); // 注意原生Date的月份是从0开始的,所以要减1 const sydneyDate = new Date( dateParts.year, parseInt(dateParts.month) - 1, dateParts.day, dateParts.hour, dateParts.minute, dateParts.second ); alert(sydneyDate);
方案4:使用成熟的日期库(最可靠,若允许引入外部库)
如果你的项目允许引入外部库,推荐用Luxon或者date-fns-tz这类专门处理时区的日期库,它们在老旧设备上的兼容性更好:
比如用Luxon的示例:
// 先引入Luxon库(网页环境可通过script标签引入) const sydneyDateTime = luxon.DateTime.now().setZone('Australia/Sydney'); alert(sydneyDateTime.toLocaleString()); // 如果需要转成原生Date对象 alert(sydneyDateTime.toJSDate());
内容的提问来源于stack exchange,提问作者Optional
相关产品推荐
相关产品推荐

