You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Safari中Javascript日期格式化返回NaN(React天气应用故障)

问题根因

这是iOS Safari浏览器的Date构造函数的字符串格式兼容性问题:
OpenWeatherMap接口返回的dt_txt字段格式为YYYY-MM-DD HH:MM:SS,Chrome等PC端浏览器支持这种用空格分隔日期和时间的写法,但Safari仅兼容ISO 8601规范的YYYY-MM-DDTHH:MM:SS格式(需将日期和时间之间的空格替换为T)。
你直接将dt_txt传入new Date()在Safari中会生成Invalid Date对象,后续调用getMonth()、getDay()这类方法就会返回NaN,触发你自定义的错误提示。

解决方案

方案1:转换日期字符串格式(快速修复)

修改formattedDateTime和formattedWeekDay两个工具函数,传入Date构造函数前先替换日期字符串中的空格为T:

function formattedDateTime(dateTimeText = '', lang = 'en', formattingMonthFunction = monthName) {
    // 替换空格为T适配Safari日期格式要求
    const safeDateStr = dateTimeText.replace(' ', 'T');
    const date = new Date(safeDateStr);
    // 原有逻辑保持不变
    const month = formattingMonthFunction(date.getMonth(), lang);
    const day = date.getDate();
    const hours = date.getHours();
    const minutes = date.getMinutes();
    return `${month} ${day}, ${hours === 0 ? '00' : hours}:${minutes < 10 ? '0' + minutes : minutes}`;
}

function formattedWeekDay(dateTimeText = '', lang = 'en', formattingFunction = weekdays) {
    const safeDateStr = dateTimeText.replace(' ', 'T');
    const date = new Date(safeDateStr);
    return formattingFunction(date.getDay(), lang);
}

方案2:使用时间戳(更稳妥,推荐)

OpenWeatherMap返回的每一条天气数据都自带Unix秒级时间戳字段dt,所有浏览器都完美支持时间戳生成日期对象,不需要处理字符串格式兼容问题:
修改Clean5DaysForecastData函数中传参逻辑,直接传递时间戳给格式化函数:

export function Clean5DaysForecastData(data, tempUnit = 'C', lang = 'en', formattingCityFunction = formattedCity) {
    const city = formattingCityFunction(data.city);
    const dataLength = data.list.length;
    const filteredList = [];
    for (let index = 0; index < dataLength; index += 8) {
        const item = data.list[index];
        const singleData = {};
        singleData['description'] = firstCharToUpper(item.weather[0].description);
        singleData['temperature'] = formattedTemperature(item.main.temp, tempUnit);
        // 传入秒级时间戳转成毫秒,后续格式化函数直接用时间戳生成Date对象
        singleData['dateTime'] = formattedDateTime(item.dt * 1000, lang);
        singleData['weekDay'] = formattedWeekDay(item.dt * 1000, lang);
        singleData['icon'] = item.weather[0].icon;
        filteredList.push(singleData);
    }
    return [city, filteredList];
}

对应的格式化函数不需要再处理字符串,直接用传入的时间戳生成Date对象即可:

function formattedDateTime(timestamp = 0, lang = 'en', formattingMonthFunction = monthName) {
    const date = new Date(timestamp);
    // 原有逻辑保持不变
}

function formattedWeekDay(timestamp = 0, lang = 'en', formattingFunction = weekdays) {
    const date = new Date(timestamp);
    // 原有逻辑保持不变
}

两种方案修改后PC端和iOS端都可以正常运行,方案2彻底规避了日期字符串格式的兼容性风险,更推荐使用。

内容的提问来源于stack exchange,提问作者elG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 16:45:04