Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 862
Mikhail Avatar asked Oct 05 '16 14:10

Mikhail


2 Answers

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.

like image 98
Timothy Jannace Avatar answered Nov 11 '22 06:11

Timothy Jannace


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.

like image 39
kiziu Avatar answered Nov 11 '22 06:11

kiziu