617 字
3 分钟
C# 计算 DateTime 时间差:从基础到进阶实战
在开发考勤系统、倒计时功能或任务调度时,计算两个时间点之间的差值是高频需求。C# 通过 DateTime 和 TimeSpan 提供了一套极简且强大的 API。
1. 核心机制:DateTime 相减
在 C# 中,计算时间差不需要复杂的计算,直接使用减法运算符 - 即可获得一个 TimeSpan 对象。
DateTime startTime = new DateTime(2025, 1, 1, 8, 0, 0);DateTime endTime = DateTime.Now;
// 核心操作:直接相减TimeSpan ts = endTime - startTime;2. 区分 Total 属性与普通属性
这是初学者最容易踩的坑。TimeSpan 提供了两组属性,其含义完全不同:
TotalDays,TotalHours…: 返回的是总跨度。例如,1.5 天会返回TotalHours = 36。Days,Hours…: 返回的是时间分量。例如,1.5 天会返回Days = 1, Hours = 12。
常用计算方法封装:
// 获取总天数(向上取整,常用于计算有效期)public int GetTotalDays(DateTime start, DateTime end) => (int)Math.Ceiling((end - start).TotalDays);
// 获取总秒数(常用于缓存过期或 Token 校验)public double GetTotalSeconds(DateTime start, DateTime end) => (end - start).TotalSeconds;3. 高级扩展:处理精度与舍入
在实际业务中,我们往往需要”忽略秒”或者”不满一小时按一小时计”。
public int DiffFullMinutes(DateTime start, DateTime end){ TimeSpan ts = end - start; // 使用 (int) 会直接截断小数,实现"向下取整" return (int)ts.TotalMinutes;}4. 跨时区的”深水区”
当你的服务器在 A 国,用户在 B 国时,直接使用 DateTime.Now 计算差值会产生灾难性的 Bug。
黄金法则: 在计算时间差时,永远优先将时间转换为 UTC (协调世界时)。
public double SafeDiffMinutes(DateTime start, DateTime end){ // 统一转换为 UTC 再计算,消除夏令时和偏移量干扰 return (end.ToUniversalTime() - start.ToUniversalTime()).TotalMinutes;}此外,如果你需要处理带偏移量的时间,推荐使用 DateTimeOffset 类型代替 DateTime。
5. 性能与精度小贴士
- 精度问题:
TimeSpan的最小单位是Tick(100 纳秒)。对于绝大多数 Web 应用,秒级精度绰绰有余。 - 只读性:
TimeSpan是不可变的。每次Add或Subtract都会返回一个新的对象。 - .NET 6+ 新选择:如果你只需要计算”一天之内”的时间差(不涉及日期),可以使用
TimeOnly类型,内存占用更小。
总结
计算时间差的精髓在于理解 TimeSpan 这个”时间容器”。
- 如果要算长度,用
TotalXXX。 - 如果要按格式显示(如 01:30:00),用普通的
Hours/Minutes。
C# 计算 DateTime 时间差:从基础到进阶实战
https://sw.rscclub.website/posts/csharpdatetimecha/