文章目录
最佳实践:赋值时指定时区
避免 C# 版本默认读取时采用 机器时区问题
如果需要UTC 时间,date=DateTime.UtcNow.Date 当下直接使用是足够的。
如果有保存的需要,那么 使用 date=DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Utc); 赋值,再次读取 date.Date 时可以强制保留时区信息。
问题描述
LastRolloverDate = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Utc);
和
LastRolloverDate = DateTime.UtcNow.Date;
再下次 读取 LastRolloverDate 时的区别
回答
关键区别:DateTime.SpecifyKind 的作用
这两行代码的主要区别在于 DateTime.Kind 属性的设置,这会影响后续读取 state.LastRolloverDate 时的行为。
1. 直接赋值 DateTime.UtcNow.Date
state.LastRolloverDate = DateTime.UtcNow.Date;
DateTime.UtcNow 的 Kind 已经是 DateTimeKind.Utc,但 .Date 会返回一个新的 DateTime,其 Kind 可能保留也可能丢失(取决于 .NET 版本和运行环境)。
在大多数现代 .NET 版本(如 .NET Core 3.1+ / .NET 5+)中,.Date 会保留 Kind,因此 state.LastRolloverDate.Kind 仍然是 Utc。
但在某些旧版本或特殊情况下(如数据库存储后读取),Kind 可能会变成 Unspecified。
读取时的表现
var lastRollover = state.LastRolloverDate;
Console.WriteLine(lastRollover.Kind); // 可能是 `Utc` 或 `Unspecified`
如果 Kind 是 Utc:后续比较或计算时,会被明确视为 UTC 时间。
如果 Kind 是 Unspecified:可能被误当作本地时间,导致逻辑错误。
2. 使用 DateTime.SpecifyKind 强制指定
state.LastRolloverDate = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Utc);
显式设置 Kind 为 Utc,确保无论 .Date 是否保留 Kind,最终值的 Kind 一定是 Utc。
完全避免 Unspecified 的潜在问题,适合需要严格 UTC 的场景(如跨时区系统、数据库存储)。
读取时的表现
var lastRollover = state.LastRolloverDate;
Console.WriteLine(lastRollover.Kind); // 一定是 `Utc
无论后续如何传递或存储,只要 Kind 未被手动修改,读取时始终是 Utc。