Работа с датами в C# (.NET): от встроенных средств до специализированных библиотек
Работа с датами и временем — одна из ключевых задач в разработке любого приложения: от веб-сервисов до десктопных утилит. Платформа .NET предоставляет мощные встроенные средства, такие как DateTime, DateTimeOffset и TimeSpan. Однако в сложных сценариях (работа с часовыми поясами, человекочитаемые интервалы, парсинг нестандартных форматов) разработчики часто обращаются к сторонним библиотекам. В этой статье мы разберём основные инструменты для работы с датами в C#.
1. Встроенные средства .NET
Базовые типы для работы с датами в .NET:
DateTime— представляет момент времени (дата + время). Поддерживает операции сложения, вычитания, сравнения.DateTimeOffset— аналог DateTime, но с явным указанием смещения относительно UTC. Рекомендуется для хранения дат в распределённых системах.TimeSpan— интервал времени (например, 2 часа 30 минут).DateOnlyиTimeOnly(с .NET 6) — для раздельного хранения даты и времени без лишних данных.
Пример использования DateTime:
using System;
DateTime now = DateTime.Now;
DateTime utcNow = DateTime.UtcNow;
DateTime specificDate = new DateTime(2025, 3, 15, 14, 30, 0);
// Форматирование
string formatted = now.ToString("dd.MM.yyyy HH:mm:ss");
Console.WriteLine(formatted); // 15.03.2025 14:30:00
// Арифметика
DateTime tomorrow = now.AddDays(1);
TimeSpan diff = tomorrow - now;
Console.WriteLine($"До завтра: {diff.TotalHours} часов");
Парсинг дат из строк:
string dateStr = "2025-03-15";
if (DateTime.TryParse(dateStr, out DateTime result))
{
Console.WriteLine(result.ToShortDateString());
}
// Парсинг с указанием культуры
var culture = new System.Globalization.CultureInfo("ru-RU");
DateTime parsed = DateTime.Parse("15 марта 2025", culture);
2. Noda Time — продвинутая работа с датами и временем
Noda Time — альтернативная библиотека от сообщества, созданная для устранения недостатков встроенного DateTime. Главные особенности:
- Чёткое разделение понятий: Instant (момент в UTC), LocalDateTime (дата+время без привязки к зоне), ZonedDateTime (с часовым поясом).
- Полная поддержка часовых поясов через базу данных IANA (Olson).
- Неизменяемые (immutable) типы — безопасны в многопоточном коде.
- Человекочитаемые интервалы (
Period): 2 года, 3 месяца, 5 дней.
Пример работы с Noda Time:
using NodaTime;
using NodaTime.Text;
// Текущий момент в UTC
Instant now = SystemClock.Instance.GetCurrentInstant();
Console.WriteLine($"Instant: {now}");
// Преобразование в локальное время с часовым поясом
DateTimeZone zone = DateTimeZoneProviders.Tzdb["Europe/Moscow"];
ZonedDateTime moscowTime = now.InZone(zone);
Console.WriteLine($"Время в Москве: {moscowTime}");
// Парсинг даты в определённом формате
var pattern = LocalDatePattern.CreateWithInvariantCulture("yyyy-MM-dd");
LocalDate date = pattern.Parse("2025-03-15").Value;
Console.WriteLine(date); // 15 марта 2025
// Работа с периодами
LocalDate start = new LocalDate(2025, 1, 1);
LocalDate end = new LocalDate(2025, 12, 31);
Period period = Period.Between(start, end, PeriodUnits.Days);
Console.WriteLine($"Дней между датами: {period.Days}");
3. Humanizer — человекочитаемые даты и интервалы
Humanizer — библиотека для преобразования чисел, дат и строк в удобный для человека вид. В контексте дат она позволяет:
- Получить относительное время: "3 минуты назад", "через 2 дня".
- Склонять названия месяцев и дней недели (важно для русского языка).
- Форматировать временные интервалы: "1 час 30 минут".
Пример с Humanizer:
using Humanizer;
using Humanizer.Localisation;
DateTime pastDate = DateTime.Now.AddHours(-3);
string relative = pastDate.Humanize();
Console.WriteLine(relative); // "3 часа назад