Go 中实现带序数后缀(如 1st、2nd)的英文日期格式化

8次阅读

Go 中实现带序数后缀(如 1st、2nd)的英文日期格式化

go 的 time.format() 不支持自动添加日期序数后缀(如 “1st”“2nd”),需手动拼接后缀逻辑,再结合标准布局字符串完成格式化。

go 中,time.Format() 严格遵循预定义的参考时间(Mon Jan 2 15:04:05 MST 2006)进行布局解析,它不支持动态文本替换(例如 “2nd” 中的 “nd” 并非占位符,而是字面量)。因此,直接使用 “Monday 2nd January” 会导致 2 被固定渲染为字面字符 “2”,而后缀 “nd” 始终原样输出,无法随日期变化——这正是示例中 4nd 和 1nd 错误结果的根源。

要实现符合英语习惯的“verbose date”(如 Wednesday 4th March 或 Sunday 1st March),必须将日期序数后缀(st/nd/rd/th)动态计算并注入格式字符串中。以下是一个简洁、健壮的实现:

func formatVerboseDate(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" 占位日,再替换为带后缀的完整日字符串     base := t.Format("Monday 2 January 2006")     return strings.Replace(base, " 2 ", fmt.Sprintf(" %d%s ", day, suffix), 1) }

✅ 注意:上述实现使用 strings.Replace(..., 1) 精确替换第一个 " 2 "(含空格),避免误替其他数字;同时正确处理了英语中的特殊规则:11–13 日统一用 "th"(即 11th, 12th, 13th),而非 11st。

更推荐的无依赖写法(不引入 strings 包)是直接构造字符串:

func formatVerboseDate(t time.Time) string {     day := t.Day()     var suffix string     switch {     case day%100 >= 11 && day%100 <= 13:         suffix = "th"     case day%10 == 1:         suffix = "st"     case day%10 == 2:         suffix = "nd"     case day%10 == 3:         suffix = "rd"     default:         suffix = "th"     }     return fmt.Sprintf("%s %d%s %s %d",         t.Weekday().String(),         day,         suffix,         t.Month().String(),         t.Year(),     ) }

该函数输出完全可控,例如:

  • time.Date(2025, 3, 1, 0, 0, 0, 0, time.UTC) → "Sunday 1st March 2025"
  • time.Date(2025, 3, 11, 0, 0, 0, 0, time.UTC) → "Tuesday 11th March 2025"
  • time.Date(2025, 3, 22, 0, 0, 0, 0, time.UTC) → "Friday 22nd March 2025"

? 总结:Go 标准库不提供序数日期格式化能力,但通过组合 t.Day()、条件判断与 fmt.Sprintf(),可轻松、高效、可读地实现符合本地化习惯的 verbose date 输出。关键在于理解 time.Format() 的静态布局本质,并主动承担动态部分的逻辑。

text=ZqhQzanResources