Newtonsoft Json 序列化 TimeSpan 格式化

11

是否可以为TimeSpan序列化指定自定义格式?使用Newtonsoft.Json

我想要格式为HH:mm的序列化字符串,例如:

TimeSpan.FromHours(5) -> // "+05:00"

TimeSpan.FromHours(-5) -> // "-05:00"

谢谢!

3个回答

21

这是一个可以添加到您的项目中的TimeSpan转换器:

using System;
using Newtonsoft.Json;

namespace JsonTools
{
    /// <summary>
    /// TimeSpans are not serialized consistently depending on what properties are present. So this 
    /// serializer will ensure the format is maintained no matter what.
    /// </summary>
    public class TimespanConverter : JsonConverter<TimeSpan>
    {
        /// <summary>
        /// Format: Days.Hours:Minutes:Seconds:Milliseconds
        /// </summary>
        public const string TimeSpanFormatString = @"d\.hh\:mm\:ss\:FFF";

        public override void WriteJson(JsonWriter writer, TimeSpan value, JsonSerializer serializer)
        {
            var timespanFormatted = $"{value.ToString(TimeSpanFormatString)}";
            writer.WriteValue(timespanFormatted);
        }

        public override TimeSpan ReadJson(JsonReader reader, Type objectType, TimeSpan existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            TimeSpan parsedTimeSpan;
            TimeSpan.TryParseExact((string)reader.Value, TimeSpanFormatString, null, out parsedTimeSpan);
            return parsedTimeSpan;
        }
    }
}

可以这样使用:

public class Schedule
{
    [JsonConverter(typeof(TimespanConverter))]
    [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
    public TimeSpan Delay { get; set; }
}

注意事项:

  1. TimeSpan序列化格式的参考资料

  2. 我发现在使用Newtonsoft生成模式时,必须包含TypeNameHandling属性,否则TimeSpan类型名称在生成的模式中不会被正确序列化。虽然这对此处的目的并非必需,但我仍然将其包括在内。


6

正如您可以在源代码中看到的那样,没有预定义设置可以更改格式(例如DateTime)。

您可以编写一个新的JsonConverter来处理TimeSpan的格式,并根据需要进行格式化。只需确保通过将其包含在JsonSerializerSettings.Converters中或修改默认设置来使用它。


0
你可以获取一个DateTime实例,然后对其进行时间加减操作,例如:
System.DateTime timeNow = System.DateTime.Now;
DateTime futureDateTime = timeNow.Add(new TimeSpan(5, 0, 0));
DateTime prevDateTime = timeNow.Add(new TimeSpan(-5, 0, 0));

指定您需要的时间。然后将它们放入您的字符串格式中:

futureDateTime.ToString("hh:mm") // 12 hour clock

为了将字符串值反序列化回具有特定格式的 DateTime 对象,此文章中提供了一个指定 DateTimeFormat 和 IsoDateTimeConverter 的示例: 使用 Json.Net 反序列化 dd/mm/yyyy 格式的日期


2
这是不正确的。如果您想像这样黑掉 DateTime,您必须使用 <someDate>.Date,例如 DateTime.Now.Date(又名 DateTime.Today),以便时间组件为空并且添加的 TimeSpan 被正确呈现。此外,这仅适用于小于 24 小时的值,而且仅适用于非负值 - 您如何在 DateTime 中表示负时间组件? - kiziu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接