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

如何使用NodaTime和System.Text.Json反序列化无末尾Z的Instant?

解决NodaTime Instant解析无Z后缀UTC时间的问题

默认情况下,NodaTime的System.Text.Json转换器要求UTC时间字符串符合ISO 8601标准(带有Z后缀),而你的JSON时间字符串缺少Z,导致解析失败。以下是两种可行的解决方案:

方案一:自定义Instant转换器

实现一个自定义的JsonConverter,直接解析不带Z的UTC时间字符串:

public class InstantWithoutZConverter : JsonConverter<Instant>
{
    // 定义匹配无Z后缀的UTC时间格式
    private static readonly InstantPattern _parsePattern = InstantPattern.CreateWithInvariantCulture("yyyy-MM-dd'T'HH:mm:ss");

    public override Instant Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var dateStr = reader.GetString() ?? throw new JsonException("时间字符串为空");
        var parseResult = _parsePattern.Parse(dateStr);
        
        if (!parseResult.Success)
            throw new JsonException($"解析Instant失败:{parseResult.ErrorMessage}");
        
        return parseResult.Value;
    }

    public override void Write(Utf8JsonWriter writer, Instant value, JsonSerializerOptions options)
    {
        // 序列化时输出标准带Z的格式
        writer.WriteStringValue(value.ToString("o", CultureInfo.InvariantCulture));
    }
}

使用时替换默认转换器:

var options = new JsonSerializerOptions()
    .ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);

// 移除默认的Instant转换器,添加自定义转换器
var defaultInstantConverter = options.Converters.First(c => c.CanConvert(typeof(Instant)));
options.Converters.Remove(defaultInstantConverter);
options.Converters.Add(new InstantWithoutZConverter());

var item = JsonSerializer.Deserialize<Item>(jsonString, options);

方案二:修改默认转换器的解析模式

直接修改NodaTime默认转换器的时间匹配模式,无需自定义转换器:

var options = new JsonSerializerOptions()
    .ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);

// 获取默认的Instant转换器并更新解析模式
var instantConverter = (NodaTimeJsonConverter<Instant>)options.Converters.First(c => c.CanConvert(typeof(Instant)));
instantConverter.Pattern = InstantPattern.CreateWithInvariantCulture("yyyy-MM-dd'T'HH:mm:ss");

var item = JsonSerializer.Deserialize<Item>(jsonString, options);

两种方案都能安全解析无Z后缀的UTC时间(前提是你确认输入时间确实为UTC),方案一更灵活,适合需要额外处理逻辑的场景;方案二更简洁,仅修改现有配置即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:05:19