Skip to main content
Version: 2.14.1

Humanize relative dates and times

Orientation

Relative humanization compares a temporal value with a known base and returns text such as yesterday, 3 hours ago, or a month from now. Pass both the comparison base and culture when output must be deterministic. Choose the overload that preserves the semantics of DateTime, DateTimeOffset, DateOnly, or TimeOnly.

Example

The example compares two UTC DateTime values and never reads the machine clock:

Program.cs
using System.Globalization;
using Humanizer;

var culture = CultureInfo.GetCultureInfo("en-US");
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;

var comparison = new DateTime(2025, 1, 20, 12, 0, 0, DateTimeKind.Utc);
var relative = comparison.AddDays(-1).Humanize(
utcDate: true,
dateToCompareAgainst: comparison,
culture: culture);
var duration = TimeSpan.FromMinutes(125).Humanize(precision: 2, culture: culture);

AssertEqual("yesterday", relative);
AssertEqual("2 hours, 5 minutes", duration);

Console.WriteLine($"{relative}; {duration}");

static void AssertEqual(string expected, string actual)
{
if (actual != expected)
throw new InvalidOperationException($"Expected '{expected}', got '{actual}'.");
}

Choose the temporal type

TypeComparison meaning
DateTimeLocal or UTC behavior selected by utcDate and Kind
DateTimeOffsetTwo offset-aware instants
DateOnlyCalendar dates without a time of day
TimeOnlyTimes of day without a calendar date

Nullable overloads return the locale’s “never” phrase for null. That is useful for optional activity timestamps but should not replace explicit missing-value handling in domain logic.

Configure thresholds once

The default strategies choose familiar boundaries such as “yesterday.” PrecisionDateTimeHumanizeStrategy and its sibling strategies use a precision factor when applications need more gradual thresholds. Assign a strategy through Configurator once during startup.

Pitfall

Do not compare a local DateTime with a UTC base accidentally. Humanizer converts the injected comparison according to utcDate; mixed Kind values can move the boundary. TimeOnly has no date context, so a comparison around midnight cannot know whether the intended event was yesterday or tomorrow.

Version notes

DateTime and DateTimeOffset support span the documented corpus. DateOnly and TimeOnly humanization begin in 2.11.10 on compatible target frameworks. Strategy types and thresholds are selected-version behavior.