You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET中SystemClock.UtcNow.Millisecond为何始终返回0?

问题现象

服务中注入ISystemClock获取时间时,返回的DateTime实例Millisecond属性恒为0,直接实例化内置SystemClock取值结果一致,但直接调用DateTime.UtcNow、DateTimeOffset.UtcNow可获取到正常的毫秒数值。
对应业务实现代码:

public class EventSink
{
    private readonly ISystemClock _systemClock;

    public EventSink(ISystemClock systemClock)
    {
        _systemClock = systemClock;
    }

    private async Task SaveEvent(CancellationToken ct)
    {
        var event = new MyEvent
        {
            Timestamp = _systemClock.UtcNow.DateTime
        };
    }
}

原服务注册代码:

services.AddScoped<ISystemClock, SystemClock>();

即时窗口测试输出:

DateTime.UtcNow.Millisecond
786
new SystemClock().UtcNow.Millisecond
0
System.DateTimeOffset.UtcNow.Millisecond;
265
原因

当前使用的SystemClock是ASP.NET Core早期鉴权组件内置的默认实现,类内部写死了时间截断逻辑:会将时间Ticks值对1秒对应的Ticks数取模,抹除所有不足1秒的时间片段,最终返回的时间精度仅到整秒,因此毫秒属性永远返回0,属于该旧实现的既定设计,不是运行时异常。

修复方式

根据项目实际情况二选一即可:

  • 项目为ASP.NET Core 8及以上版本:直接废弃旧的ISystemClock抽象,改用框架官方新增的TimeProvider时间抽象,默认TimeProvider.System实现返回的时间携带完整精度,单元测试时Mock逻辑也更简洁,直接注入使用即可。
  • 项目需兼容旧代码必须保留ISystemClock接口:不要使用内置的精度截断版SystemClock,自行实现高精度版本替换:
public class HighPrecisionSystemClock : ISystemClock
{
    public DateTimeOffset UtcNow => DateTimeOffset.UtcNow;
}

注册时替换原有实现:

services.AddScoped<ISystemClock, HighPrecisionSystemClock>();

替换后通过ISystemClock获取的时间就会携带正确的毫秒值。

内容的提问来源于stack exchange,提问作者Yoda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:01:06