DateTime.Now.AddDays()是最直接的日期增减方法,支持正负整数及小数,自动处理闰年、月末等边界,推荐用DateTime.Today.AddDays(-1)获取昨日零点,注意本地时间与UTC转换以避免时区错误。

DateTime.Now.AddDays() 是最直接的解法
想拿昨天或明天,别绕弯子——DateTime.Now.AddDays(-1) 和 DateTime.Now.AddDays(1) 就够用。这个方法底层走的是日历算术,会自动处理月末、闰年、时区偏移等边界,比手动拼字符串或改 Day 属性靠谱得多。
常见错误是写成 DateTime.Now.Day - 1,这只会返回一个整数(比如今天 1 号就变 0),根本不是日期类型,后续调用 .ToString() 或传给数据库会直接报错或存成 0001-01-01。
- 参数为负数:往前推天数;正数:往后推天数
- 支持小数,比如
AddDays(0.5)表示加 12 小时,但日常用整数就够了 - 结果仍是
DateTime类型,可链式调用.Date去掉时间部分
需要固定“昨天零点”?用 .Date 配合 AddDays()
很多场景(比如查昨日全天日志、统计报表)要的是“昨天 00:00:00”,不是“此刻减 24 小时”。直接 DateTime.Now.AddDays(-1) 会带上当前时间分秒,容易漏数据或重复计算。
正确做法是先取今天零点,再减一天:DateTime.Today.AddDays(-1)。注意 DateTime.Today 等价于 DateTime.Now.Date,两者都返回不含时分秒的日期。
-
DateTime.Today比DateTime.Now.Date更语义清晰,推荐优先用 - 如果业务严格要求 UTC 时间,得用
DateTime.UtcNow.Date.AddDays(-1) - 别用
new DateTime(year, month, day)手动构造——硬编码年月易出错,且不跨时区
LocalTime 和 UTC 混用会悄悄出错
系统默认用本地时区,但数据库、API、日志服务可能全走 UTC。如果你在本地跑 DateTime.Now.AddDays(-1) 得到 2024-05-19 14:30,而数据库存的是 UTC 时间,那实际对应的是 2024-05-19 06:30(假设东八区),查询时就可能对不上。
判断依据很简单:看你的数据源和目标系统是否统一时区。不统一,就得提前转换:
- 入库前转 UTC:
DateTime.Now.ToUniversalTime().AddDays(-1) - 从 UTC 时间还原本地时间:
utcTime.ToLocalTime().AddDays(-1) - 用
DateTimeKind检查值的时区标识:dt.Kind是Unspecified时,多数 API 会当本地时间处理,隐患很大
性能和线程安全不用操心,但别在循环里反复调 Now
DateTime.Now 和 AddDays() 都是轻量级操作,没有锁、不 IO、不分配大对象,单次调用开销可忽略。但如果你在高频循环里写 for (int i = 0; i ,每次都会触发系统时钟读取,不仅多余,还可能因毫秒级变化导致结果不一致。
正确做法是把基准时间提出来算一次:
var now = DateTime.Now; var yesterday = now.AddDays(-1); var tomorrow = now.AddDays(1);
真要处理大量时间运算(比如逐分钟生成时间轴),考虑用 DateTimeOffset 替代 DateTime,它自带时区偏移信息,避免隐式转换歧义。











