简体   繁体   中英

newtonsoft json serialize timespan format

Is it possible to specify custom format for TimeSpan serialization? Using Newtonsoft.Json .

I would like to have serialized string in format HH:mm, so for example:

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

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

Thanks!

As you can see in the source code , there is no way of changing the format using predefined setting (like for DateTime ).

What you can do is write a new JsonConverter for TimeSpan and handle the formatting as you see fit. Just be sure to use it by including it in JsonSerializerSettings.Converters or by modifying the default settings.

Here's a TimeSpan converter you can add to your project:

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;
        }
    }
}

It can be used like this:

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

Notes:

  1. Reference for TimeSpan serialization formats

  2. I found that when generating a schema using Newtonsoft I had to include the TypeNameHandling attribute or the TimeSpan type name was not being serialized properly in the generated schema. That isn't necessary for the purpose here, but I included it anyway.

You can get a DateTime instance, and then add and subtract time from it like:

System.DateTime timeNow = System.DateTime.Now;
DateTime futureDateTime = timeNow.Add(new TimeSpan(5, 0, 0));
DateTime prevDateTime = timeNow.Add(new TimeSpan(-5, 0, 0));

To specify the times that you need. Then to put them into your string format:

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

To deserialize the string value back into DateTime objects with a certain format, there's an example of specifying a DateTimeFormat and IsoDateTimeConverter in this post: Deserializing dates with dd/mm/yyyy format using Json.Net

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM