【发布时间】:2016-10-05 14:08:35
【问题描述】:
是否可以为TimeSpan 序列化指定自定义格式?
使用Newtonsoft.Json。
我想有HH:mm格式的序列化字符串,例如:
TimeSpan.FromHours(5) -> // "+05:00"
TimeSpan.FromHours(-5) -> // "-05:00"
谢谢!
【问题讨论】:
标签: c# json serialization
是否可以为TimeSpan 序列化指定自定义格式?
使用Newtonsoft.Json。
我想有HH:mm格式的序列化字符串,例如:
TimeSpan.FromHours(5) -> // "+05:00"
TimeSpan.FromHours(-5) -> // "-05:00"
谢谢!
【问题讨论】:
标签: c# json serialization
这是一个可以添加到项目中的 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; }
}
我发现在使用 Newtonsoft 生成架构时,我必须包含 TypeNameHandling 属性,否则 TimeSpan 类型名称未在生成的架构中正确序列化。这对于这里的目的来说不是必需的,但我还是把它包括在内了。
【讨论】:
如您所见in the source code,无法使用预定义设置更改格式(例如DateTime)。
您可以做的是为TimeSpan 编写一个新的JsonConverter 并按照您认为合适的方式处理格式。请务必通过将其包含在JsonSerializerSettings.Converters 中或修改默认设置来使用它。
【讨论】:
您可以获取一个 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 的示例: Deserializing dates with dd/mm/yyyy format using Json.Net
【讨论】:
DateTime,你必须使用<someDate>.Date,例如。 DateTime.Now.Date(又名DateTime.Today),所以时间组件是空的,添加TimeSpan 是正确的。更重要的是,这仅适用于小于 24 小时的值且仅适用于非负值 - 你想如何在 DateTime 中呈现负时间分量?