日期格式化是什么
把日期时间格式化成字符串:MySQL 用 DATE_FORMAT(d, '%Y-%m-%d'),PostgreSQL 用 to_char(d, 'YYYY-MM-DD')。两套模板字母含义不同,是迁移时最容易出错的地方:MySQL 的 %Y 是四位年,PostgreSQL 的 YYYY 才是四位年,Y 在 PostgreSQL 里只表示年份的最后一位。反方向把字符串解析成日期,MySQL 用 STR_TO_DATE,PostgreSQL 用 to_date 与 to_timestamp。格式化后的结果是字符串类型,排序与比较都不再按时间语义处理。
基本信息
| MySQL 格式化 | DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s') |
|---|---|
| PostgreSQL 格式化 | to_char(now(), 'YYYY-MM-DD HH24:MI:SS') |
| MySQL 常用占位 | %Y 四位年、%m 月、%d 日、%H 小时、%i 分钟、%s 秒 |
| PostgreSQL 模板 | YYYY、MM、DD、HH24、MI、SS |
| 字符串转日期 | MySQL 用 STR_TO_DATE,PostgreSQL 用 to_date 与 to_timestamp |
| 注意 | 格式化后是字符串,排序要按原始时间列 |
典型使用场景
- 报表展示:把时间戳格式化成人类可读的日期
- 生成批次号或文件名前缀:把日期嵌入字符串
- 按天或按月分组前的取整准备
- 接口输出:按约定的时间格式返回给前端
- 数据导出:固定格式便于下游系统解析
- 解析外部数据:把字符串日期转成日期类型再入库
示例
示例
-- MySQL
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d') AS d, # 2024-05-01
DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s') AS dt, # 到秒
DATE_FORMAT(NOW(), '%Y%m') AS ym; # 202405
SELECT STR_TO_DATE('2024-05-01', '%Y-%m-%d');
-- PostgreSQL
SELECT to_char(now(), 'YYYY-MM-DD') AS d,
to_char(now(), 'YYYY-MM-DD HH24:MI:SS') AS dt,
to_char(now(), 'YYYYMM') AS ym;
SELECT to_date('2024-05-01', 'YYYY-MM-DD');占位符对照
| 含义 | MySQL | PostgreSQL |
|---|---|---|
| 四位年 | %Y | YYYY |
| 两位月 | %m | MM |
| 两位日 | %d | DD |
| 24 小时制小时 | %H | HH24 |
| 分钟 | %i | MI |
| 秒 | %s | SS |
| 月份名(英文) | %M | Month |
两库的模板字母不能互换:PostgreSQL 里 Y 只取年份最后一位,把 MySQL 的 '%Y-%m' 直接搬过去会得到完全不同的结果。
格式化结果排序会按字符串比较:'2024-5-1' 与 '2024-05-01' 的先后与时间顺序不一致,所以排序务必用原始时间列。
在 WHERE 里对时间列套格式化函数会让索引失效;需要按天筛选用范围条件替代,例如 >= '2024-05-01' AND < '2024-05-02'。
使用要点
- 格式化统一在展示层做,SQL 里尽量保留原始时间类型
- 两库模板字母对照表贴在项目文档里,避免迁移时反复查
- 输出格式与接口文档保持一致,前后端约定唯一格式
- 需要排序或比较时用原始时间列,不用格式化后的字符串
- 解析字符串时格式要与数据完全一致,否则报错或得到错误的日期
- 时区转换放在格式化之前,顺序颠倒会得到偏移的时间