Working with Dates in C# (.NET): Built-in Tools and Popular Libraries
Working with dates and time is one of the key tasks in any serious development. In the C# (.NET) ecosystem, there are both powerful built-in types (DateTime, DateTimeOffset, TimeSpan) and third-party libraries that simplify complex operations — working with time zones, human-readable representation, parsing non-standard formats. In this article, we will thoroughly examine the main tools for working with dates in C#.
Built-in .NET Types
The base class System.DateTime provides methods for creating, comparing, arithmetic, and formatting dates. It supports a range from 01.01.0001 to 31.12.9999.
// Creating a dateDateTime now = DateTime.Now; // local timeDateTime utcNow = DateTime.UtcNow; // UTCDateTime specific = new DateTime(2025, 3, 15, 14, 30, 0);
// ArithmeticDateTime tomorrow = now.AddDays(1);TimeSpan diff = tomorrow - now;Console.WriteLine(diff.TotalHours); // 24
// Parsingstring dateStr = "2025-12-31";DateTime parsed = DateTime.Parse(dateStr, CultureInfo.InvariantCulture);
// FormattingConsole.WriteLine(now.ToString("dd.MM.yyyy HH:mm")); // 15.03.2025 14:30DateTimeOffset is an enhanced version that stores the offset relative to UTC. It is recommended for applications working with different time zones.
DateTimeOffset nowOffset = DateTimeOffset.Now;Console.WriteLine(nowOffset.Offset); // +03:00 (depends on system)TimeSpan — for representing time intervals. Ideal for measuring operation durations.
TimeSpan duration = new TimeSpan(2, 15, 30); // 2 hours 15 minutes 30 secondsConsole.WriteLine(duration.TotalMinutes); // 135.5NodaTime Library
NodaTime is an alternative library for working with dates and time, created by Jon Skeet (author of books on C#). It solves many problems with DateTime, such as ambiguity and lack of strict typing for time zones.
Installation via NuGet:
dotnet add package NodaTimeMain types:
Instant— a moment in time (analogous to Unix timestamp)LocalDateTime— date+time without time zone bindingZonedDateTime— date+time in a specific time zoneDurationandPeriod— intervals (analogous to TimeSpan, but Period accounts for calendar units)
using NodaTime;
// Current moment in UTCInstant now = SystemClock.Instance.GetCurrentInstant();Console.WriteLine(now.ToDateTimeUtc()); // can be converted to DateTime
// Working with time zonesDateTimeZone tz = DateTimeZoneProviders.Tzdb["Europe/Moscow"];ZonedDateTime moscowTime = now.InZone(tz);Console.WriteLine(moscowTime); // 2025-03-15T17:30:00 Europe/Moscow (+03)
// Period — difference in calendar unitsLocalDate start = new LocalDate(2024, 1, 1);LocalDate end = new LocalDate(2025, 3, 15);Period period = Period.Between(start, end);Console.WriteLine($"Elapsed {period.Years} years, {period.Months} months, {period.Days} days");// Elapsed 1 years, 2 months, 14 daysAdvantages of NodaTime: strict typing, correct handling of historical time zones, support for calendars (Islamic, Hebrew, etc.), no ambiguities during clock changes.
Humanizer Library
Humanizer is a library for "humanizing" data, including dates and intervals. It allows displaying dates in a human-readable form: "yesterday", "in 3 hours", "2 days ago".
Installation:
dotnet add package HumanizerUsage examples