Working with Dates in C# (.NET): From Built-in Tools to Specialized Libraries
Working with dates and time is one of the key tasks in developing any application: from web services to desktop utilities. The .NET platform provides powerful built-in tools such as DateTime, DateTimeOffset, and TimeSpan. However, in complex scenarios (working with time zones, human-readable intervals, parsing non-standard formats), developers often turn to third-party libraries. In this article, we will cover the main tools for working with dates in C#.
1. Built-in .NET Tools
Basic types for working with dates in .NET:
DateTime— represents a moment in time (date + time). Supports addition, subtraction, and comparison operations.DateTimeOffset— an analog of DateTime, but with an explicit offset relative to UTC. Recommended for storing dates in distributed systems.TimeSpan— a time interval (e.g., 2 hours 30 minutes).DateOnlyandTimeOnly(since .NET 6) — for separate storage of date and time without extra data.
Example of using DateTime:
using System;
DateTime now = DateTime.Now;DateTime utcNow = DateTime.UtcNow;DateTime specificDate = new DateTime(2025, 3, 15, 14, 30, 0);
// Formattingstring formatted = now.ToString("dd.MM.yyyy HH:mm:ss");Console.WriteLine(formatted); // 15.03.2025 14:30:00
// ArithmeticDateTime tomorrow = now.AddDays(1);TimeSpan diff = tomorrow - now;Console.WriteLine($"Until tomorrow: {diff.TotalHours} hours");Parsing dates from strings:
string dateStr = "2025-03-15";if (DateTime.TryParse(dateStr, out DateTime result)){ Console.WriteLine(result.ToShortDateString());}
// Parsing with culture specificationvar culture = new System.Globalization.CultureInfo("ru-RU");DateTime parsed = DateTime.Parse("15 March 2025", culture);2. Noda Time — Advanced Date and Time Handling
Noda Time is an alternative community library created to address the shortcomings of the built-in DateTime. Main features:
- Clear separation of concepts: Instant (a moment in UTC), LocalDateTime (date+time without time zone binding), ZonedDateTime (with time zone).
- Full time zone support via the IANA (Olson) database.
- Immutable types — safe for multithreaded code.
- Human-readable intervals (
Period): 2 years, 3 months, 5 days.
Example of working with Noda Time:
using NodaTime;using NodaTime.Text;
// Current moment in UTCInstant now = SystemClock.Instance.GetCurrentInstant();Console.WriteLine($"Instant: {now}");
// Conversion to local time with time zoneDateTimeZone zone = DateTimeZoneProviders.Tzdb["Europe/Moscow"];ZonedDateTime moscowTime = now.InZone(zone);Console.WriteLine($"Time in Moscow: {moscowTime}");
// Parsing a date in a specific formatvar pattern = LocalDatePattern.CreateWithInvariantCulture("yyyy-MM-dd");LocalDate date = pattern.Parse("2025-03-15").Value;Console.WriteLine(date); // 15 March 2025
// Working with periodsLocalDate start = new LocalDate(2025, 1, 1);LocalDate end = new LocalDate(2025, 12, 31);Period period = Period.Between(start, end, PeriodUnits.Days);Console.WriteLine($"Days between dates: {period.Days}");3. Humanizer — Human-Readable Dates and Intervals
Humanizer is a library for converting numbers, dates, and strings into a human-friendly format. In the context of dates, i