638 字
3 分钟
C# 常用时间范围获取指南:当天、周、月、上月

在后端开发中,经常需要根据时间范围查询数据库(如报表统计)。正确获取时间区间的“起点”和“终点”是确保数据准确性的关键。本文将提供一套标准的 C# 实现方案。


🛠️ 核心工具类:DateTimeHelper#

建议将这些逻辑封装在工具类中,避免在业务代码中重复编写冗长的计算逻辑。

public static class DateTimeHelper
{
/// <summary>
/// 获取当天起止时间
/// </summary>
public static (DateTime start, DateTime end) GetTodayRange()
{
var start = DateTime.Today; // 00:00:00
var end = start.AddDays(1).AddSeconds(-1); // 23:59:59
return (start, end);
}
/// <summary>
/// 获取本周起止时间 (以周一为起点)
/// </summary>
public static (DateTime start, DateTime end) GetCurrentWeekRange()
{
int offset = (int)DateTime.Today.DayOfWeek;
// 处理 DayOfWeek.Sunday 为 0 的特殊情况
int dayDiff = (offset == 0 ? 7 : offset) - 1;
var start = DateTime.Today.AddDays(-dayDiff);
var end = start.AddDays(7).AddSeconds(-1);
return (start, end);
}
/// <summary>
/// 获取本月起止时间
/// </summary>
public static (DateTime start, DateTime end) GetCurrentMonthRange()
{
var now = DateTime.Now;
var start = new DateTime(now.Year, now.Month, 1);
var end = start.AddMonths(1).AddSeconds(-1);
return (start, end);
}
/// <summary>
/// 获取上个月起止时间
/// </summary>
public static (DateTime start, DateTime end) GetLastMonthRange()
{
var firstDayOfThisMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
var start = firstDayOfThisMonth.AddMonths(-1);
var end = firstDayOfThisMonth.AddSeconds(-1);
return (start, end);
}
}

📖 核心逻辑深度解析#

1. 边界处理:为什么要 AddSeconds(-1)#

在 C# 的 DateTime 处理中,我们通常将一天的结束定义为 23:59:59

  • 技巧:先跳转到下一阶段的起始点(如明天、下月 1 号),然后减去 1 秒。
  • 注意:在 SQL 查询时,如果使用 BETWEEN,这种写法非常有效;但如果数据库字段精度到毫秒,建议使用 start <= time && time < nextPeriodStart 的开闭区间逻辑。

2. 本周起点的陷阱#

C# 中的 DayOfWeek 枚举中,Sunday 的值是 0

  • 如果你习惯将周一作为一周的第一天,直接减去 (int)DayOfWeek 会导致周日计算错误。
  • 优化逻辑:使用 (offset == 0 ? 7 : offset) - 1 可以完美兼容中国习惯。

3. 性能小贴士#

  • **DateTime.Now vs DateTime.Today**:如果你只需要日期部分,请优先使用 DateTime.Today,它比 DateTime.Now.Date 少了一步解析当前时间的操作,性能更佳。

🚀 进阶:EF Core 数据库查询示例#

在实际应用中,我们通常结合 LINQ 进行查询:

var range = DateTimeHelper.GetLastMonthRange();
var orders = await _context.Orders
.Where(o => o.CreateTime >= range.start && o.CreateTime <= range.end)
.ToListAsync();

总结#

掌握 DateTime 的位移方法(AddDays, AddMonths)是处理时间业务的基础。通过合理的工具类封装,可以显著降低代码的维护成本并减少“差一秒”类的 Bug。

C# 常用时间范围获取指南:当天、周、月、上月
https://sw.rscclub.website/posts/casharpqzsj/
作者
杨月昌
发布于
2016-07-18
许可协议
CC BY-NC-SA 4.0