go 的 `time.format()` 不支持自动添加英文日期序数词后缀(如 "1st"、"2nd"),需手动拼接;本文提供简洁可靠的自定义格式化函数,并涵盖边界处理与本地化扩展建议。
Go 标准库的 time.Time.Format() 方法基于固定布局字符串(如 "2006-01-02")进行格式化,其占位符(如 "2" 表示日)仅输出纯数字,不支持语言学意义上的序数词(ordinal suffixes)——即不会将 1 转为 1st、2 转为 2nd 等。因此,直接使用 "Monday 2nd January" 会导致字面量 "2nd" 被原样保留,而 2 占位符仍输出实际日期数字(如 4),最终变成 "4nd",显然不符合预期。
要实现正确效果,核心思路是:分离格式化逻辑——先用 t.Format() 生成不含日序数词的骨架字符串,再动态插入带后缀的日期数字。以下是一个生产就绪的实现:
func formatDate(t time.Time) string {
day := t.Day()
var suffix string
switch {
case day%100 >= 11 && day%100 <= 13:
suffix = "th" // 11th, 12th, 13th are special cases
case day%10 == 1:
suffix = "st"
case day%10 == 2:
suffix = "nd"
case day%10 == 3:
suffix =
"rd"
default:
suffix = "th"
}
// 使用 Format() 拼接:替换掉原始布局中的 "2" 占位符,注入 "Xth" 形式
base := t.Format("Monday ") + fmt.Sprintf("%d%s", day, suffix) + t.Format(" January")
return base
}✅ 关键改进说明:
? 使用示例:
t := time.Date(2025, 3, 1, 0, 0, 0, 0, time.UTC) fmt.Println(formatDate(t)) // 输出:Sunday 1st March t = time.Date(2025, 3, 11, 0, 0, 0, 0, time.UTC) fmt.Println(formatDate(t)) // 输出:Tuesday 11th March
⚠️ 注意事项:
通过这一轻量封装,你就能在 Go 中稳定输出符合英语习惯的“Wednesday 4th March”这类自然日期格式,兼顾准确性与可维护性。