您好!欢迎访问家园网-www.jy.wang!

家园网

mysql中格式化日期溯源

网络 作者:本站 点击:

在mysql中格式化日期很方便,比如%a表示简写的英文星期,%b表示简写的英文月份,等等,

请将其可以使用的日期/时间格式列出,并从词源的角度或者其他角度解释为什么使用这个字母来代表,

比如%a,那为什么百分号加上小写a就表示简写的英文星期了呢?


这是一个很有意思的问题。在 MySQL 中,%a 表示简写的星期名称(如 Sun、Mon),其选择逻辑并不是基于英文首字母(因为 %w 已经被用作星期几的数字,%W 是全写星期),而是遵循了一套源于 C 语言标准库 strftime() 函数的传统惯例

为了让你既看到全貌又理解来源,我将这些格式符分为几类,并从词源/编码历史角度解释原因。

一、从 C 语言 strftime() 继承的“简写”逻辑

MySQL 的 DATE_FORMAT() 函数直接借鉴了 C 语言的 strftime()(string format time)。早期的 Unix 开发者需要为每个日期时间组件指定一个格式符。

核心规则:

  • 大写字母 通常表示 “完整/正式” 的格式。

  • 小写字母 通常表示 “简写/数字” 或 “变体” 格式。

格式符含义词源/解释
%a简写星期名 (Sun..Sat)取英文 Abbreviation(简写)的首字母。虽然 a 不是 week 的首字母,但 C 语言中 %A 已被用作完整星期名,因此用小写 a 表示 Abbreviation 是一种惯例。
%b简写月份名 (Jan..Dec)同样取 Abbreviation,但 %a 已占用星期,%A 占用完整星期,月份简写自然顺延到 %b(可能源于 Brief 或简单继承 C 语言既有定义)。实际上 strftime 中 %b 就是简写月份。
%c完整日期时间源于 C 语言的“combined”或“canonical”(标准组合),表示日期和时间的标准表示法(如 2008-01-02 15:30:00 的某种格式)。
%d月份中的天数 (01..31)Day of the month。
%e月份中的天数 (1..31),无前导零可能源于“extra”或“elapsed”,但在 C 语言中设计为 %d 的“空格填充”版本,MySQL 中改为无前导零的数字。
%f微秒 (000000..999999)Fractional seconds(小数秒)。
%H小时 (00..23)24 小时制,Hour。
%h小时 (01..12)12 小时制,与 %I 功能相同。取 Hour 的小写变体。
%I小时 (01..12)12 小时制,大写 I 可能因为形状像 1,或者与 %H(24 小时)形成对照。
%i分钟 (00..59)Minute 被 %M(月份名)占用,所以取 i 作为 minute 中的一个字母(可能是 internal 或中间的意思)。
%j年中的天数 (001..366)Julian day(儒略日)的变体,表示一年中的第几天。
%k小时 (0..23),无前导零可能源于 Klock(德语/北欧语中表示“钟”),或简单作为 %H 的无填充版本。
%l小时 (1..12),无前导零小写 L,可能源于 Lower(12 小时制的小时数字较小)。
%M月份名 (January..December)Month 全称。
%m月份数字 (01..12)Month 的小写表示数字版本。
%pAM 或 PMPeriod(时间段)或 Post meridiem(拉丁语“下午”)的缩写。
%r12 小时制时间 (hh:mm:ss AM/PM)可能源于 Representation(表示法),或“readable”。
%S秒 (00..59)Second。
%s秒 (00..59)小写 s 与 %S 功能相同,历史兼容性原因。
%T24 小时制时间 (hh:mm:ss)Time(24 小时制标准时间)。
%U年中的周数 (00..53),周日为一周第一天U 可能源于 Usual(常见的一种周编号规则)。
%u年中的周数 (00..53),周一为一周第一天小写 u 作为 %U 的变体,表示“周一为第一天”的 ISO 风格。
%V年中的周数 (01..53),周一为一周第一天,与 %X 配合V 可能源于 ISO 周编号中的罗马数字 5 形状,或简单作为 %v 的大写对照。
%v年中的周数 (01..53),周日为一周第一天小写 v 作为 %V 的变体。
%W完整星期名 (Sunday..Saturday)Weekday 全称。
%w星期几数字 (0=周日..6=周六)小写 w 表示 Weekday 的数字形式。
%X星期所在的年份(四位数),与 %V 配合大写 X 可能源于 ISO 周编号系统中“跨年”的特殊标记。
%x日期表示 (mm/dd/yy)小写 x 可能是“x-ch”(交换)或简单作为 %X 的变体。
%Y四位年份Year 完整。
%y两位年份小写 y 作为 Year 的简写形式。

二、为什么 %a 代表“简写星期”而不是首字母 %w

  1. 历史包袱:C 语言 strftime 设计时,%w 已被定义为“星期几的数字”(0-6)。如果再用 %w 表示简写名称,就会冲突。

  2. 类别的系统性

    • %B = 完整月份

    • %b = 简写月份

    • %A = 完整星期 → 大写 = 完整/正式

    • %a = 简写星期 → 小写 a 来自 Abbreviation(简写)

    • 同理:

  3. 字母复用逻辑:因为星期和月份是两类不同的属性,%a 和 %b 分别代表“星期简写”和“月份简写”,既避免了冲突,又通过 a/b 区分了类别(实际上只是 C 标准中的既定顺序)。

三、快速记忆技巧

类别完整版(大写)简写版(小写)记忆逻辑
星期%W (Weekday full)%a (Abbreviation of weekday)a = Abbreviation
月份%M (Month full)%b (Abbreviation of month)b = Abbreviation(但 a 已被星期占用)
小时(24h)%H (Hour)%h (12h 简写)小写 h 表示 12 小时制变体
年份%Y (Year full)%y (year short)小写 y 表示两位简写
分钟无完整版%i (minutes)i 是 minute 中间的一个字母(因 %m 被月份占用)

四、实际应用示例

-- 输出:2025-04-15 Tuesday Apr
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %W %b');
-- 输出:Tue 04/15/25 02:30 PM
SELECT DATE_FORMAT(NOW(), '%a %m/%d/%y %h:%i %p');

总结

MySQL 的日期格式符主要继承自 C 语言 strftime 函数,其字母选择遵循:

  1. 大写 = 完整格式(Full)

  2. 小写 = 简写/数字格式(Abbreviation/Numeric)

  3. %a 中的 a 代表 Abbreviation(简写),而不是 Week 的首字母,因为 %w 已经被“星期几的数字”占用了。

这种设计虽然初看有些奇怪,但一旦理解了“大写完整/小写简写”的规则以及历史继承关系,就能很快记住大部分格式符


标签: