From a70238f84a1f3cf8b1d668e062628d60d8e7a81e Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 01:30:17 +0000 Subject: [PATCH] feat(numbers): add locale-aware ordinals Co-Authored-By: Virgil --- numbers.go | 9 +++++++++ numbers_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/numbers.go b/numbers.go index f3aa3e6..c324d29 100644 --- a/numbers.go +++ b/numbers.go @@ -129,6 +129,8 @@ func FormatOrdinal(n int) string { lang = lang[:idx] } switch lang { + case "fr": + return formatFrenchOrdinal(n) case "en": return formatEnglishOrdinal(n) default: @@ -136,6 +138,13 @@ func FormatOrdinal(n int) string { } } +func formatFrenchOrdinal(n int) string { + if n == 1 || n == -1 { + return core.Sprintf("%der", n) + } + return core.Sprintf("%de", n) +} + func formatEnglishOrdinal(n int) string { abs := n if abs < 0 { diff --git a/numbers_test.go b/numbers_test.go index df4d59b..40717ab 100644 --- a/numbers_test.go +++ b/numbers_test.go @@ -147,6 +147,39 @@ func TestFormatOrdinal(t *testing.T) { } } +func TestFormatOrdinalFromLocale(t *testing.T) { + svc, err := New() + if err != nil { + t.Fatalf("New() failed: %v", err) + } + prev := Default() + SetDefault(svc) + t.Cleanup(func() { + SetDefault(prev) + }) + + if err := SetLanguage("fr"); err != nil { + t.Fatalf("SetLanguage(fr) failed: %v", err) + } + + tests := []struct { + n int + want string + }{ + {1, "1er"}, + {2, "2e"}, + {3, "3e"}, + {11, "11e"}, + } + + for _, tt := range tests { + got := FormatOrdinal(tt.n) + if got != tt.want { + t.Errorf("FormatOrdinal(fr, %d) = %q, want %q", tt.n, got, tt.want) + } + } +} + func TestFormatNumberFromLocale(t *testing.T) { svc, err := New() if err != nil { -- 2.45.3