先解析成时刻再格式化
各语言与平台的时间格式记号互不相同,靠字符串替换互相转换必然出错。规范做法是三步:用源格式解析成结构化时刻(含时区),在结构化层做运算或换算,再用目标格式输出。这样转换过程与记号的差异解耦,出问题也只需检查其中一段。
基本信息
| POSIX 记号 | 百分号形式,如 %Y-%m-%d %H:%M:%S,见于 C、Python、date 命令 |
|---|---|
| Java 与 .NET 记号 | 字母形式,如 uuuu-MM-dd HH:mm:ss、yyyy-MM-dd HH:mm:ss |
| JS 生态记号 | Intl 与内置格式化,或日期库的 YYYY-MM-DD HH:mm:ss 形式 |
| Go 记号 | 不使用占位字母,而是用固定参考时间 2006-01-02 15:04:05 作为模板 |
| 电子表格 | 底层是序列号,显示格式与存储值分离,需注意单元格类型 |
典型使用场景
- 接口迁移:把某一家的时间串改写成另一家要求的格式
- 日志规范化:统一成 ISO 8601 便于检索与排序
- 导出报表:源数据是毫秒时间戳,展示需要本地可读格式
- 跨语言联调:确认 mm 在两边的含义是否一致
- 解析用户输入:先按一组候选格式解析,避免误判
记号对照与示例
记号对照与示例
# 同一时刻 2026-10-17 09:30:00+08:00 的多种写法
POSIX/Python : %Y-%m-%d %H:%M:%S%z -> 2026-10-17 09:30:00+0800
Java/.NET : uuuu-MM-dd HH:mm:ssXXX -> 2026-10-17 09:30:00+08:00
JS 日期库 : YYYY-MM-DD HH:mm:ssZ -> 2026-10-17 09:30:00+08:00
Go : 2006-01-02 15:04:05-07:00 -> 2026-10-17 09:30:00+08:00
# 关键对应:年 Y/yyyy,月 M/MM,日 d/dd,时 H/HH,分 m/mm,秒 s/ss,小数秒 f/SSS
# 注意大小写敏感:m 是月还是分,取决于所用记号体系记号对应速查
| 含义 | POSIX | Java 与 .NET | JS 日期库 |
|---|---|---|---|
| 四位年 | %Y | uuuu 或 yyyy | YYYY |
| 月 | %m | MM | MM |
| 日 | %d | dd | DD |
| 二十四小时 | %H | HH | HH |
| 分 | %M | mm | mm |
| 秒 | %S | ss | ss |
| 小数秒 | %f | SSS 等单位 | SSS |
| 带冒号偏移 | %z 通常无冒号 | XXX | Z |
Java 建议用 uuuu 而非 yyyy:yyyy 表示纪元年份,严格解析时需要同时提供纪元信息,跨纪元或年份补零的输入容易解析失败;具体取舍以官方文档为准。
电子表格的时间格式存在上下文歧义:同一个字母在小时之后的位置表示分钟,在日期位置表示月份。把时间当文本导入还可能被识别成数值序列号,导入前先指定列的文本类型。