React Native 时区转换与日期格式化跨端统一展示问题求解
解决方案
原生JS方案(无需引入第三方库)
现有代码的核心问题有两个:
- 直接解析MySQL返回的无标识UTC时间字符串时,iOS和Android的JS引擎解析逻辑不一致,Android默认不会将不带时区标识的字符串识别为UTC时间
toLocaleTimeString默认跟随系统设置展示12/24小时制,没有强制统一格式规则,导致两端表现不同
优化后的代码直接解决上述问题,同时支持自定义时区、输出格式:
const DateConvert = (rawDate, customOptions = {}) => { // 把MySQL的UTC字符串转成标准带UTC标识的格式,确保跨平台解析结果完全一致 const utcDateStr = rawDate.replace(' ', 'T') + 'Z'; const targetDate = new Date(utcDateStr); // 基础默认配置,可通过customOptions完全覆盖 const defaultOptions = { // 不传时区默认用设备本地时区,可传入用户存在数据库的自定义时区,如 Asia/Shanghai timeZone: customOptions.timeZone || Intl.DateTimeFormat().resolvedOptions().timeZone, weekday: 'short', // 输出星期简称,要数字星期改为 'numeric' year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: customOptions.hour12 ?? true, // 强制默认12小时制,传false则为24小时制 }; return new Intl.DateTimeFormat('zh-CN', {...defaultOptions, ...customOptions}).format(targetDate); };
使用示例:
- 输出默认12小时制本地时区时间:
DateConvert('2021-09-11 00:22:00') - 输出24小时制指定时区时间:
DateConvert('2021-09-11 00:22:00', {timeZone: 'Asia/Shanghai', hour12: false}) - 输出带数字星期的格式:
DateConvert('2021-09-11 00:22:00', {weekday: 'numeric'})
注意:如果需要兼容Android 8以下的冷门时区,原生方案可能存在兼容问题,建议使用第三方库方案。
第三方库方案(更稳定灵活,开发效率更高)
推荐使用轻量、支持按需引入的date-fns,是目前替代moment.js的主流方案,对跨平台兼容性做了充分适配:
- 安装依赖
npm install date-fns date-fns-tz
- 封装工具函数
import { format, utcToZonedTime } from 'date-fns-tz'; import { zhCN } from 'date-fns/locale'; /** * @param {string} rawDate MySQL存储的UTC时间字符串,如 2021-09-11 00:22:00 * @param {string} targetTimeZone 目标时区,不传默认用设备本地时区 * @param {string} formatStr 输出格式模板,默认输出 Fri 09/09/2021, 10:29 pm 格式 * @returns 格式化后的时间字符串 */ const DateConvert = (rawDate, targetTimeZone, formatStr = 'EEE MM/dd/yyyy, hh:mm a') => { const utcDateStr = rawDate.replace(' ', 'T') + 'Z'; const utcDate = new Date(utcDateStr); const zonedDate = utcToZonedTime(utcDate, targetTimeZone || Intl.DateTimeFormat().resolvedOptions().timeZone); return format(zonedDate, formatStr, { locale: zhCN }); };
使用示例:
- 输出默认12小时制格式:
DateConvert('2021-09-11 00:22:00') - 输出24小时制上海时区时间:
DateConvert('2021-09-11 00:22:00', 'Asia/Shanghai', 'EEE MM/dd/yyyy, HH:mm') - 输出数字星期格式:
DateConvert('2021-09-11 00:22:00', undefined, 'i MM/dd/yyyy, HH:mm')
内容的提问来源于stack exchange,提问作者Fonewiz
相关产品推荐
相关产品推荐

