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

如何在C#中用System.Text.Json反序列化Java Duration至NodaTime Duration?

解决方法

要将Java输出的这种多负号格式的Duration字符串反序列化为NodaTime的Duration类型,需要自定义System.Text.Json转换器来适配格式差异,具体步骤如下:

1. 依赖准备

确保项目已安装以下NuGet包:

  • NodaTime
  • NodaTime.Serialization.SystemTextJson

2. 自定义Json转换器

创建继承自JsonConverter<Duration>的类,在读取逻辑中处理Java风格的特殊Duration格式:

using System.Text.Json;
using System.Text.Json.Serialization;
using NodaTime;
using NodaTime.Text;

public class JavaDurationConverter : JsonConverter<Duration>
{
    public override Duration Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var durationStr = reader.GetString();
        if (string.IsNullOrWhiteSpace(durationStr))
            return Duration.Zero;

        // 处理Java风格的多负号格式:将"PT-328H-46M-43.2082074S"转为标准ISO格式"-PT328H46M43.2082074S"
        bool hasNegativeComponents = durationStr.Contains("-");
        if (hasNegativeComponents)
        {
            var normalizedStr = "-" + durationStr.Replace("-", "");
            var pattern = DurationPattern.CreateWithInvariantCulture("'%'PTHHmmss.FFFFFFF");
            var parseResult = pattern.Parse(normalizedStr);
            if (parseResult.Success)
                return parseResult.Value;
        }

        // 兼容正常ISO格式的解析
        var defaultPattern = DurationPattern.Roundtrip;
        var defaultParseResult = defaultPattern.Parse(durationStr);
        return defaultParseResult.Success ? defaultParseResult.Value : Duration.Zero;
    }

    public override void Write(Utf8JsonWriter writer, Duration value, JsonSerializerOptions options)
    {
        // 序列化时输出标准ISO格式,也可根据需求改为Java风格
        writer.WriteStringValue(DurationPattern.Roundtrip.Format(value));
    }
}

3. 应用转换器反序列化

将自定义转换器加入JsonSerializerOptions,即可完成反序列化:

var options = new JsonSerializerOptions();
options.Converters.Add(new JavaDurationConverter());

// 示例反序列化操作
var jsonStr = "\"PT-328H-46M-43.2082074S\"";
var nodaDuration = JsonSerializer.Deserialize<Duration>(jsonStr, options);

// 验证结果(输出应为 -328:46:43.2082074)
Console.WriteLine(nodaDuration);

格式说明

Java的Duration会为每个负分量单独添加负号,而NodaTime默认遵循ISO 8601标准(仅在整个Duration前添加一个负号)。自定义转换器的核心是将Java格式转换为NodaTime可识别的标准格式,再通过DurationPattern完成解析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:42:36