在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 的小写表示数字版本。 |
%p | AM 或 PM | Period(时间段)或 Post meridiem(拉丁语“下午”)的缩写。 |
%r | 12 小时制时间 (hh:mm:ss AM/PM) | 可能源于 Representation(表示法),或“readable”。 |
%S | 秒 (00..59) | Second。 |
%s | 秒 (00..59) | 小写 s 与 %S 功能相同,历史兼容性原因。 |
%T | 24 小时制时间 (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?
历史包袱:C 语言
strftime设计时,%w已被定义为“星期几的数字”(0-6)。如果再用%w表示简写名称,就会冲突。类别的系统性:
%B= 完整月份%b= 简写月份%A= 完整星期 → 大写 = 完整/正式%a= 简写星期 → 小写a来自 Abbreviation(简写)同理:
字母复用逻辑:因为星期和月份是两类不同的属性,
%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 函数,其字母选择遵循:
大写 = 完整格式(Full)
小写 = 简写/数字格式(Abbreviation/Numeric)
%a中的a代表 Abbreviation(简写),而不是 Week 的首字母,因为%w已经被“星期几的数字”占用了。
这种设计虽然初看有些奇怪,但一旦理解了“大写完整/小写简写”的规则以及历史继承关系,就能很快记住大部分格式符