当前位置: 首页 > article >正文

前端国际化进阶:日期时间格式化完全指南

前端国际化进阶日期时间格式化完全指南前言各位前端大佬们今天咱们来聊聊国际化开发中的老大难问题——日期时间格式化。想象一下美国人看到05/23/2024以为是五月二十三号英国人看到23/05/2024才明白是五月二十三号日本人看到2024年5月23日会心一笑沙特人看到1445/10/15可能需要换算一下是不是头都大了别担心今天咱们就用JavaScript的Intl API来彻底解决这个问题Intl.DateTimeFormat 基础创建格式化器// 创建中文日期格式化器 const chineseFormatter new Intl.DateTimeFormat(zh-CN, { year: numeric, month: long, day: numeric, weekday: long }); console.log(chineseFormatter.format(new Date())); // 输出2024年5月23日 星期四常用选项配置// 完整的配置选项示例 const options { year: numeric, // numeric | 2-digit month: long, // numeric | 2-digit | long | short | narrow day: numeric, // numeric | 2-digit weekday: short, // long | short | narrow hour: 2-digit, // numeric | 2-digit minute: 2-digit, // numeric | 2-digit second: 2-digit, // numeric | 2-digit hour12: false, // true | false (12/24小时制) timeZone: Asia/Shanghai, timeZoneName: short // short | long }; const formatter new Intl.DateTimeFormat(zh-CN, options);实战多语言日期时间显示场景一用户注册时间显示function formatRegistrationTime(timestamp, locale) { const now new Date(); const registrationDate new Date(timestamp); const diffInMs now.getTime() - registrationDate.getTime(); const diffInDays Math.floor(diffInMs / (1000 * 60 * 60 * 24)); // 智能判断显示方式 if (diffInDays 0) { return new Intl.DateTimeFormat(locale, { hour: 2-digit, minute: 2-digit }).format(registrationDate); } else if (diffInDays 1) { return locale zh-CN ? 昨天 : Yesterday; } else if (diffInDays 7) { return new Intl.DateTimeFormat(locale, { weekday: short }).format(registrationDate); } else { return new Intl.DateTimeFormat(locale, { month: short, day: numeric }).format(registrationDate); } }场景二倒计时组件class CountdownTimer { constructor(endTime, options {}) { this.endTime new Date(endTime); this.locale options.locale || zh-CN; this.onTick options.onTick || (() {}); } start() { this.interval setInterval(() { const now new Date(); const diff this.endTime.getTime() - now.getTime(); if (diff 0) { clearInterval(this.interval); this.onTick({ expired: true }); return; } const days Math.floor(diff / (1000 * 60 * 60 * 24)); const hours Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); const seconds Math.floor((diff % (1000 * 60)) / 1000); this.onTick({ days, hours, minutes, seconds, formatted: this.formatTime(days, hours, minutes, seconds) }); }, 1000); } formatTime(days, hours, minutes, seconds) { const labels { zh-CN: { day: 天, hour: 时, minute: 分, second: 秒 }, en-US: { day: d, hour: h, minute: m, second: s }, ja-JP: { day: 日, hour: 時間, minute: 分, second: 秒 } }; const l labels[this.locale] || labels[en-US]; return ${days}${l.day} ${hours}${l.hour} ${minutes}${l.minute} ${seconds}${l.second}; } }时区处理技巧时区转换function convertTimezone(date, targetTimezone, locale zh-CN) { return new Intl.DateTimeFormat(locale, { timeZone: targetTimezone, year: numeric, month: 2-digit, day: 2-digit, hour: 2-digit, minute: 2-digit, timeZoneName: short }).format(date); } // 使用示例 const meetingTime new Date(2024-06-01T10:00:00); console.log(convertTimezone(meetingTime, America/New_York, en-US)); // 输出06/01/2024, 10:00 AM EDT console.log(convertTimezone(meetingTime, Asia/Tokyo, ja-JP)); // 输出06/01/2024 23:00 JST获取支持的时区列表function getSupportedTimezones() { return Intl.supportedValuesOf(timeZone); } // 获取常用时区 const commonTimezones [ UTC, Asia/Shanghai, Asia/Tokyo, Europe/London, America/New_York, America/Los_Angeles, Australia/Sydney ];相对时间格式化Intl.RelativeTimeFormat 使用const relativeFormatter new Intl.RelativeTimeFormat(zh-CN, { style: long, // long | short | narrow localeMatcher: best fit }); console.log(relativeFormatter.format(-1, day)); // 昨天 console.log(relativeFormatter.format(0, day)); // 今天 console.log(relativeFormatter.format(1, day)); // 明天 console.log(relativeFormatter.format(-7, day)); // 7天前 console.log(relativeFormatter.format(12, month)); // 12个月后智能相对时间显示function formatRelativeTime(date, locale zh-CN) { const now new Date(); const diffMs date.getTime() - now.getTime(); const units [ { unit: year, ms: 1000 * 60 * 60 * 24 * 365 }, { unit: month, ms: 1000 * 60 * 60 * 24 * 30 }, { unit: week, ms: 1000 * 60 * 60 * 24 * 7 }, { unit: day, ms: 1000 * 60 * 60 * 24 }, { unit: hour, ms: 1000 * 60 * 60 }, { unit: minute, ms: 1000 * 60 }, { unit: second, ms: 1000 } ]; const formatter new Intl.RelativeTimeFormat(locale, { style: short }); for (const { unit, ms } of units) { const amount Math.round(diffMs / ms); if (Math.abs(amount) 1 || unit second) { return formatter.format(amount, unit); } } return locale zh-CN ? 刚刚 : Just now; }日历系统支持非公历日历// 伊斯兰历 const hijriFormatter new Intl.DateTimeFormat(ar-SA-u-ca-islamic, { year: numeric, month: long, day: numeric }); console.log(hijriFormatter.format(new Date())); // 输出١٤٤٥/١٠/١٥ // 希伯来历 const hebrewFormatter new Intl.DateTimeFormat(he-IL-u-ca-hebrew, { year: numeric, month: long, day: numeric }); console.log(hebrewFormatter.format(new Date()));最佳实践总结1. 统一时间存储// 始终使用UTC时间存储 function toUTCString(date) { return date.toISOString(); } // 始终使用UTC时间解析 function parseUTCString(isoString) { return new Date(isoString); }2. 延迟格式化策略// 只在渲染时进行格式化 function LocalizedDate({ date, locale, options }) { const formattedDate useMemo(() { return new Intl.DateTimeFormat(locale, options).format(date); }, [date, locale, options]); return span{formattedDate}/span; }3. 缓存格式化器const formatterCache new Map(); function getFormatter(locale, options) { const key ${locale}-${JSON.stringify(options)}; if (!formatterCache.has(key)) { formatterCache.set(key, new Intl.DateTimeFormat(locale, options)); } return formatterCache.get(key); }常见问题与解决方案Q1: Safari不支持某些时区解决方案使用polyfill或手动处理import formatjs/intl-datetimeformat/polyfill; import formatjs/intl-datetimeformat/locale-data/zh;Q2: 如何处理历史日期解决方案使用固定时区进行解析function parseHistoricalDate(dateStr, timezone) { const [year, month, day] dateStr.split(-).map(Number); const date new Date(Date.UTC(year, month - 1, day)); return date; }Q3: 用户时区如何获取解决方案通过Intl API检测function getUserTimezone() { return Intl.DateTimeFormat().resolvedOptions().timeZone; }总结日期时间国际化确实是个复杂的问题但只要掌握了Intl API的正确用法就能游刃有余。关键记住三点存储用UTC后端和数据库始终存储UTC时间显示用Local前端根据用户语言环境格式化时区要明确涉及跨时区场景时清晰标注时区信息下次遇到日期显示问题别再手动拼接字符串了Intl API才是正道如果你觉得这篇文章有帮助欢迎点赞、收藏、评论三连你的支持是我继续创作的动力

相关文章:

前端国际化进阶:日期时间格式化完全指南

前端国际化进阶:日期时间格式化完全指南 前言 各位前端大佬们,今天咱们来聊聊国际化开发中的"老大难"问题——日期时间格式化。想象一下: 美国人看到 05/23/2024 以为是五月二十三号英国人看到 23/05/2024 才明白是五月二十三号日本…...

EasyMLServe:一键部署机器学习模型,自动生成REST API与GUI界面

1. 项目概述与核心痛点做机器学习项目,尤其是搞科研的同行们,肯定都经历过这个阶段:模型在Jupyter Notebook里跑得挺好,准确率也达标了,论文也发了,但接下来呢?怎么让隔壁生物实验室的同事、或者…...

Android高版本HTTPS抓包解法:Magisk+MoveCert证书升权实战

1. 为什么高版本安卓抓包越来越像在拆炸弹? 你有没有试过在Android 12或13上用Charles抓App的HTTPS流量,结果刚装完证书就弹出“此证书不受信任”?App死活不走代理,甚至直接闪退——不是网络问题,不是Charles没配好&a…...

机器学习优化算法在激光等离子体加速实验中的应用与选型指南

1. 项目概述:当机器学习算法遇见激光等离子体加速在激光等离子体加速(Laser Wakefield Acceleration, LWFA)这类前沿物理实验中,我们常常面临一个经典难题:如何从一堆相互耦合、影响复杂的实验参数中,快速、…...

Frida hook so层解析protobuf二进制数据实战指南

1. 这不是“hook个so那么简单”:为什么 protobuf 数据成了 Frida 调试里最隐蔽的拦路虎你有没有遇到过这种情况:用 Frida 成功 hook 到某个 so 库里的关键函数,log 打得满屏飞,参数地址、返回值、调用栈一应俱全——可当你兴冲冲地…...

AI医疗转化瓶颈诊断:网络分析与LLM分类的工程实践

1. 项目概述:当AI医疗研究撞上转化“玻璃墙”在医疗健康领域,人工智能(AI)的研究论文和专利数量正以前所未有的速度增长。作为一名长期关注医疗科技转化的从业者,我亲眼见证了从早期影像识别到如今大语言模型&#xff…...

Keil MDK中自定义CMSIS代码模板实战指南

1. 自定义CMSIS用户代码模板的完整指南作为一名嵌入式开发老手,我经常需要在Keil MDK环境中创建各种RTOS任务模板。官方提供的模板虽然好用,但实际项目中我们往往需要根据公司编码规范或特定硬件平台定制专属模板。今天我就来分享如何在CMSIS环境中添加自…...

Spark Transformer:稀疏化技术提升大模型计算效率

1. Spark Transformer架构解析在深度学习领域,Transformer模型已经成为自然语言处理和多模态任务的事实标准架构。然而,随着模型规模的不断扩大和序列长度的持续增长,计算效率问题日益突出。2025年提出的Spark Transformer通过创新性地重新激…...

量子多体系统模拟:MPS与DMRG算法实践

1. 量子多体系统模拟基础框架在量子多体系统的研究中,矩阵乘积态(MPS)已成为描述一维强关联系统的标准工具。这种表示方法的核心思想是将一个N体量子态分解为N个局部张量的收缩形式,每个张量对应一个物理位点。具体数学表达为: [ |ψ⟩ \sum…...

C166链接器Error L101段冲突解决方案

1. 问题现象与背景解析当使用C166开发工具链进行项目链接时,开发者可能会遇到L166链接器报出的Error L101(Section Combination Error)。这个错误通常表现为链接过程中突然中断,并显示类似以下的错误信息:L166 LINKER …...

【Python趣味编程】用 Tkinter 打造“爱心便签墙”:一份来自代码的温柔

【Python趣味编程】用 Tkinter 打造“爱心便签墙”:一份来自代码的温柔 文章目录【Python趣味编程】用 Tkinter 打造“爱心便签墙”:一份来自代码的温柔🎯 前言🧠 核心思路关键点:💻 完整代码🔧…...

可解释AI在宏基因组学中的应用:从黑箱预测到透明洞察

1. 项目概述:当宏基因组学遇见可解释AI如果你在生物信息学或精准医疗领域工作,最近几年一定被两个词刷屏了:一个是“宏基因组学”,另一个是“可解释AI”。前者让我们得以窥见人体内万亿微生物构成的复杂宇宙,后者则试图…...

国防采购如何吸引商业AI创新:OTA协议与敏捷合作模式解析

1. 项目概述:当国防采购遇上商业AI创新在过去的十几年里,我接触过不少政府与科技企业间的合作项目,从早期的云计算服务到后来的大数据分析平台。但最近几年,一个趋势愈发明显:以人工智能为代表的颠覆性技术&#xff0c…...

AI社交对话反效果解析:期望违背与尴尬感知的机制与规避

1. 项目概述:当AI社交对话“翻车”时,发生了什么? 最近和几个做客户服务与市场营销的朋友聊天,大家不约而同地提到了一个现象:公司花大价钱部署的AI聊天机器人或者智能客服,有时候不仅没解决问题&#xff0…...

RFECV特征选择在勒索软件分类中的实战:API与网络流量特征对比

1. 项目概述:当勒索软件分类遇上RFECV特征选择在网络安全攻防的战场上,勒索软件无疑是最具破坏性和经济威胁的对手之一。它不再仅仅是技术宅的恶作剧,而是演变成了组织化、产业化的犯罪工具,其变种迭代速度之快,让传统…...

Win11自带IIS搭建局域网网站,从配置到安全避坑的保姆级指南(含MIME类型、目录浏览详解)

Win11 IIS局域网网站搭建全攻略:从零配置到安全加固在家庭或小型办公环境中,搭建一个内部网站用于知识共享或文件管理是提升协作效率的实用方案。Windows 11自带的IIS(Internet Information Services)服务为这类需求提供了轻量级解…...

知识图谱与大语言模型协同:构建材料科学精准智能问答系统

1. 项目概述:当知识图谱遇见大语言模型“想象一下,未来有这样一个设备……个人可以存储他所有的书籍、记录和通信,并且它被机械化,可以以极高的速度和灵活性进行查阅。它是他记忆的一个放大的、亲密的补充。”——范内瓦布什&…...

BERTopic与概念图理论在物理教育文本挖掘中的应用实践

1. 项目概述:当物理教育遇上文本挖掘作为一名长期关注教育数据挖掘的从业者,我常常思考一个问题:我们如何能“听见”学生在物理学习过程中的“思维声音”?传统的试卷分数、选择题对错,只能告诉我们结果,却无…...

保姆级教程:用USM的PE和分区助手,把旧硬盘数据无损搬到新硬盘(附Win11引导修复)

Win11系统硬盘无损迁移全指南:USM PE与分区助手实战详解当你面对一块崭新的固态硬盘,既想享受飞速读写体验,又担心重装系统后那些精心调试的设置和重要数据丢失,这种纠结我太熟悉了。去年我的主力机升级时,整整3TB的工…...

在Ubuntu 18.04上,用RoadRunner 2022b画的地图如何导入UE4.24给CARLA 0.9.10用?保姆级避坑指南

在Ubuntu 18.04上将RoadRunner 2022b地图导入UE4.24并适配CARLA 0.9.10的完整指南对于自动驾驶仿真开发者而言,构建一个稳定可靠的地图工作流至关重要。本文将详细介绍如何在Ubuntu 18.04系统中,将RoadRunner 2022b创建的地图无缝导入Unreal Engine 4.24…...

明星数字人运营失效率高达68%?AI Agent驱动的粉丝交互系统,已帮3家MCN提升留存率217%

更多请点击: https://intelliparadigm.com 第一章:AI Agent娱乐行业应用的现状与挑战 近年来,AI Agent在娱乐行业的渗透持续加速,从智能剧本生成、虚拟偶像实时交互,到个性化内容推荐与跨平台用户行为建模&#xff0c…...

为什么92%的餐饮AI项目6个月内失败?——头部连锁品牌CTO亲授Agent选型黄金三角模型(含成本/合规/扩展性三维评估表)

更多请点击: https://codechina.net 第一章:为什么92%的餐饮AI项目6个月内失败? 餐饮行业正经历一场由AI驱动的效率革命,但现实却异常残酷:第三方审计机构TechDine 2024年度报告显示,92%的餐饮AI项目在上线…...

AI翻译准确率99.9%,专业翻译岗位反而增加了——这说明了什么

有一组数据很有意思:AI翻译的准确率已经能到99.9%,速度快,成本低,理论上完全具备替代人工翻译的能力。但实际情况是,专业翻译岗位的需求这几年不降反升。这背后的逻辑,对理解芯片工程师的核心价值也很有启发…...

Claude如何30分钟完成PubMed万级文献综述?——基于NEJM、Lancet真实案例的提示工程拆解

更多请点击: https://codechina.net 第一章:Claude医学文献分析案例 在临床研究与循证医学实践中,研究人员常需从海量PubMed、NEJM或Lancet等来源的PDF或HTML格式文献中快速提取关键信息。Claude系列大模型凭借其长上下文(最高20…...

全球仅17家机构掌握的PlayAI教育大模型微调技术(含3所双一流高校内部调参手册节选)

更多请点击: https://intelliparadigm.com 第一章:PlayAI教育大模型微调技术的全球稀缺性与战略价值 在全球人工智能教育应用加速落地的背景下,PlayAI教育大模型微调技术已成为少数国家与头部机构掌握的核心能力。其稀缺性不仅源于算力、数据…...

JWT签名机制与常见攻击实战:从PortSwigger靶场12关学透算法混淆、密钥混淆与JWKS劫持

1. 为什么JWT不是“加密令牌”,而是“签名凭证”——从PortSwigger靶场第一关开始讲起很多人一看到JWT就下意识觉得:“这是个加密的token,只要我拿到它,就等于拿到了用户密码或者敏感密钥。”这种误解直接导致他们在实战中反复碰壁…...

别再只会用T检验了!用Python+SciPy搞定Z检验,5分钟判断两组数据差异是否显著

用Python实战Z检验:5分钟判断业务数据差异显著性当你手头有两组A/B测试结果或不同版本的产品指标时,如何快速判断它们的均值差异是否具有统计学意义?很多数据分析师的第一反应是使用T检验,但当你面对大样本数据时,Z检验…...

PlayAI在特殊教育中的突破性应用:自闭症儿童社交训练响应率提升4.8倍的神经反馈模型首次公开

更多请点击: https://kaifayun.com 第一章:PlayAI教育领域应用案例 PlayAI 是一个面向教育场景的轻量级AI交互平台,支持教师快速构建可对话、可评估、可追踪的学习代理。其核心优势在于无需深度学习背景即可配置多轮问答逻辑、知识图谱链接…...

AI企业参与国防采购的挑战、机遇与实操路线图

1. 项目概述:当AI遇见国防采购,一场静默的“双向奔赴”在硅谷的咖啡厅和五角大楼的简报室之间,正上演着一场深刻而复杂的对话。话题的核心,是人工智能这项被誉为“新时代电力”的技术,如何融入世界上最庞大、最严谨的采…...

线性化多噪声训练:提升混沌系统长期预测稳定性的正则化技术

1. 项目概述:当机器学习遇上混沌,如何让预测“长治久安”?在天气预报、气候模拟乃至金融市场分析中,我们常常需要面对一类“混沌系统”。这类系统的特点是,其短期行为虽然遵循确定的规律,但长期演化对初始条…...