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

C#中Serilog日志@t时间戳时区设置问题(TimeWrap已弃用)

解决Serilog CompactJsonFormatter时间戳时区问题(替代已弃用的TimeWrap)

嘿,我之前也碰到过这个问题——CompactJsonFormatter默认输出UTC+0的@t时间戳,而且老的TimeWrap方法已经不能用了。这里有两个靠谱的方案帮你把时间戳改成目标时区:

方案1:通过Enricher调整日志事件的时间戳

你可以在日志配置里,通过WithTimestamp指定自定义的时间戳生成逻辑,直接把UTC时间转换为目标时区的DateTimeOffset:

// 先获取你需要的目标时区,比如中国标准时间(UTC+8)
var targetTimeZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");

Log.Logger = new LoggerConfiguration()
    // 替换默认的UTC时间戳为目标时区时间
    .Enrich.WithTimestamp(() => 
        TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, targetTimeZone))
    .WriteTo.File(new CompactJsonFormatter(), "app-logs.json")
    .CreateLogger();

小贴士:可以通过TimeZoneInfo.GetSystemTimeZones()枚举系统支持的时区ID,比如美国东部时区是"Eastern Standard Time",欧洲中部是"Central European Standard Time"。

方案2:自定义CompactJsonFormatter子类

如果需要更灵活的控制(比如不想修改全局日志事件的时间戳,只在格式化输出时转换),可以继承CompactJsonFormatter并重写时间戳的处理逻辑:

public class TimeZoneAwareCompactJsonFormatter : CompactJsonFormatter
{
    private readonly TimeZoneInfo _targetTimeZone;

    public TimeZoneAwareCompactJsonFormatter(TimeZoneInfo targetTimeZone)
    {
        _targetTimeZone = targetTimeZone ?? throw new ArgumentNullException(nameof(targetTimeZone));
    }

    protected override void WriteEvent(TextWriter output, LogEvent logEvent)
    {
        // 将原始UTC时间戳转换为目标时区的DateTimeOffset
        var localDateTime = TimeZoneInfo.ConvertTimeFromUtc(logEvent.Timestamp.UtcDateTime, _targetTimeZone);
        var adjustedTimestamp = new DateTimeOffset(localDateTime, _targetTimeZone.GetUtcOffset(localDateTime));

        // 创建一个调整了时间戳的新日志事件
        var adjustedLogEvent = new LogEvent(
            adjustedTimestamp,
            logEvent.Level,
            logEvent.Exception,
            logEvent.MessageTemplate,
            logEvent.Properties.Select(p => new LogEventProperty(p.Key, p.Value))
        );

        // 调用父类方法输出调整后的事件
        base.WriteEvent(output, adjustedLogEvent);
    }
}

使用这个自定义格式化器的方式很简单:

var targetTimeZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
Log.Logger = new LoggerConfiguration()
    .WriteTo.File(new TimeZoneAwareCompactJsonFormatter(targetTimeZone), "app-logs.json")
    .CreateLogger();

两种方案都能让你的@t字段输出带正确时区偏移的时间戳,比如"2020-02-19T21:34:55.6398202+08:00"(对应你示例中的UTC时间转换为UTC+8后的结果)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 16:37:40