C# (.NET) 中的日期处理:内置工具与流行库
日期和时间处理是任何严肃开发中的关键任务之一。在 C# (.NET) 生态系统中,既有强大的内置类型(DateTime、DateTimeOffset、TimeSpan),也有简化复杂操作(如时区处理、人类可读表示、非标准格式解析)的第三方库。本文将详细解析 C# 中用于日期处理的主要工具。
.NET 内置类型
基础类 System.DateTime 提供了创建、比较、算术运算和格式化日期的方法。它支持的日期范围从 0001 年 1 月 1 日到 9999 年 12 月 31 日。
// 创建日期DateTime now = DateTime.Now; // 本地时间DateTime utcNow = DateTime.UtcNow; // UTCDateTime specific = new DateTime(2025, 3, 15, 14, 30, 0);
// 算术运算DateTime tomorrow = now.AddDays(1);TimeSpan diff = tomorrow - now;Console.WriteLine(diff.TotalHours); // 24
// 解析string dateStr = "2025-12-31";DateTime parsed = DateTime.Parse(dateStr, CultureInfo.InvariantCulture);
// 格式化Console.WriteLine(now.ToString("dd.MM.yyyy HH:mm")); // 15.03.2025 14:30DateTimeOffset 是一个增强版本,存储相对于 UTC 的偏移量。建议用于处理不同时区的应用程序。
DateTimeOffset nowOffset = DateTimeOffset.Now;Console.WriteLine(nowOffset.Offset); // +03:00 (取决于系统)TimeSpan 用于表示时间间隔。非常适合测量操作持续时间。
TimeSpan duration = new TimeSpan(2, 15, 30); // 2 小时 15 分钟 30 秒Console.WriteLine(duration.TotalMinutes); // 135.5NodaTime 库
NodaTime 是一个用于日期和时间处理的替代库,由 Jon Skeet(C# 书籍作者)创建。它解决了 DateTime 的许多问题,例如歧义性和时区缺乏强类型化。
通过 NuGet 安装:
dotnet add package NodaTime主要类型:
Instant— 时间点(类似于 Unix 时间戳)LocalDateTime— 不带时区的日期+时间ZonedDateTime— 特定时区的日期+时间Duration和Period— 间隔(类似于 TimeSpan,但 Period 考虑日历单位)
using NodaTime;
// 当前 UTC 时间点Instant now = SystemClock.Instance.GetCurrentInstant();Console.WriteLine(now.ToDateTimeUtc()); // 可转换为 DateTime
// 时区处理DateTimeZone tz = DateTimeZoneProviders.Tzdb["Europe/Moscow"];ZonedDateTime moscowTime = now.InZone(tz);Console.WriteLine(moscowTime); // 2025-03-15T17:30:00 Europe/Moscow (+03)
// Period — 日历单位的差异LocalDate start = new LocalDate(2024, 1, 1);LocalDate end = new LocalDate(2025, 3, 15);Period period = Period.Between(start, end);Console.WriteLine($"经过了 {period.Years} 年, {period.Months} 月, {period.Days} 天");// 经过了 1 年, 2 月, 14 天NodaTime 的优势:强类型化、正确处理历史时区、支持多种日历(伊斯兰历、希伯来历等)、消除夏令时转换时的歧义。
Humanizer 库
Humanizer 是一个用于“人性化”数据的库,包括日期和时间间隔。它允许以人类可读的形式显示日期,例如:“昨天”、“3 小时后”、“2 天前”。
安装:
dotnet add package Humanizer使用示例