Humanizr/Humanizer · error · NotSupportedException
The formatter for '{culture?.Name ?? CultureInfo.CurrentCult
Error message
The formatter for '{culture?.Name ?? CultureInfo.CurrentCulture.Name}' does not support grammatical-case-aware durations. What it means
Thrown by FormatTimePart when a grammatical case is requested for word-based output but the culture's IFormatter does not implement IGrammaticalCaseTimeSpanFormatter. Not all locale formatters support case inflection; this guard prevents silent fallback to the uninflected form.
Source
Thrown at src/Humanizer/TimeSpanHumanizeExtensions.cs:916
toSymbols,
grammaticalCase)
: null;
internal static string FormatTimePart(
IFormatter cultureFormatter,
TimeUnit timeUnit,
int amount,
CultureInfo? culture,
bool toWords,
bool toSymbols,
GrammaticalCase? grammaticalCase) =>
toSymbols
? string.Concat(amount.ToString(culture ?? CultureInfo.CurrentCulture), cultureFormatter.TimeUnitHumanize(timeUnit))
: grammaticalCase is null
? cultureFormatter.TimeSpanHumanize(timeUnit, amount, toWords)
: cultureFormatter is IGrammaticalCaseTimeSpanFormatter caseFormatter
? caseFormatter.TimeSpanHumanize(timeUnit, amount, grammaticalCase.Value)
: throw new NotSupportedException(
$"The formatter for '{culture?.Name ?? CultureInfo.CurrentCulture.Name}' does not support grammatical-case-aware durations.");
static string HumanizeSinglePart(
TimeSpan timeSpan,
CultureInfo? culture,
TimeUnit maxUnit,
TimeUnit minUnit,
bool toWords,
bool toSymbols,
GrammaticalCase? grammaticalCase)
{
var cultureFormatter = Configurator.GetFormatter(culture);
foreach (var timeUnit in TimeUnits)
{
var timePart = GetTimeUnitPart(
timeUnit,
timeSpan,
maxUnit,View on GitHub (pinned to ffc2b77c0f)
Solutions
- Use a culture whose formatter implements IGrammaticalCaseTimeSpanFormatter (e.g. Slavic locales).
- Pass grammaticalCase: null for locales without case support.
- Implement IGrammaticalCaseTimeSpanFormatter on your custom formatter.
Example fix
// before
var s = ts.HumanizeWithCase(GrammaticalCase.Genitive, precision: 3, culture: new CultureInfo("en"));
// after
var s = ts.HumanizeWithCase(GrammaticalCase.Genitive, precision: 3, culture: new CultureInfo("ru"));
// or omit case for English: ts.Humanize(precision: 3) Defensive patterns
Strategy: type-guard
Validate before calling
static bool FormatterSupportsCase(IFormatter formatter) =>
formatter is IGrammaticalCaseTimeSpanFormatter; Type guard
static bool CanHumanizeCaseForCulture(CultureInfo? culture)
{
var formatter = Configurator.GetFormatter(culture);
return formatter is IGrammaticalCaseTimeSpanFormatter;
} Prevention
- Check the formatter implements IGrammaticalCaseTimeSpanFormatter before requesting a case.
- Use locales known to support case (e.g. Russian, Polish) for case-aware output.
- Fall back to null grammaticalCase for unsupported locales.
When it happens
Trigger: Calling HumanizeWithCase or a case-aware humanize with a culture whose formatter (e.g. English DefaultFormatter) does not implement IGrammaticalCaseTimeSpanFormatter. The formatter's type is checked at line 914.
Common situations: Requesting Genitive or Dative case for English or another locale that doesn't inflect time units by case. Using a locale that only supports the base IFormatter interface. Passing a culture from user preference that lacks case support.
Related errors
- Custom formatter type '{GetType().FullName}' must explicitly
- Culture '{Culture.Name}' has no grammatical-case classificat
- Culture '{Culture.Name}' has an applicable grammatical case
- Culture '{Culture.Name}' does not support grammatical-case d
- Culture '{Culture.Name}' does not support grammatical case '
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/301042075660c9f0.
Report an issue: GitHub.