I have a dynamic object that contains dates (among other data).
Some of these dates have Kind UTC and others have Kind Local, eg:
var dynamicObject = new
{
utcDate = DateTime.UtcNow, //This one has Kind = DateTimeKind.Utc
localDate = DateTime.Now //This one has Kind = DateTimeKind.Local
}
And then I have a JsonSerializer that works as follows:
var isoDateTimeConverter = new IsoDateTimeConverter();
isoDateTimeConverter.DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'";
// ^
// Notice this
var serializerSettings = new JsonSerializerSettings();
SerializerSettings.Converters.Add(isoDateTimeConverter);
var response = context.HttpContext.Response;
var writer = new JsonTextWriter(response.Output) { Formatting = Formatting };
var serializer = JsonSerializer.Create(serializerSettings);
serializer.Serialize(writer, dynamicObject);
writer.Flush();
Which creates a JSON string as this:
{
"utcDate":"2019-05-02T19:52:20Z",
"localDate":"2019-05-02T15:52:20Z"
}
This is expected because of how my isoDateTimeConverter
is currently defined.
But I'd like to serialize as follows:
{
"utcDate":"2019-05-02T19:52:20Z",
"localDate":"2019-05-02T15:52:20" // <--- no Z
}
Meaning that I'd like to add a 'Z' only when the Kind of the DateTime is Utc.
Is this possible with IsoDateTimeConverter
and/or JsonSerializerSettings
?
I would either use IsoDateTimeConverter
without setting the DateTimeFormat
, which outputs the full DateTime
value, with fractions of seconds, and a "Z" if the DateTimeKind
is UTC
or a time zone offset in "+-HH:mm" format if Local
(and the empty string if None
).
Otherwise, the K
specifier will format the value as you desire, appending the same values for the offset from UTC.
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public class Program
{
public static void Main(string[] args)
{
var dynamicObject = new
{
utcDate = DateTime.UtcNow, //This one has Kind = DateTimeKind.Utc
localDate = DateTime.Now //This one has Kind = DateTimeKind.Local
}
;
var isoDateTimeConverter = new IsoDateTimeConverter();
isoDateTimeConverter.DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK";
var serializerSettings = new JsonSerializerSettings();
serializerSettings.Converters.Add(isoDateTimeConverter);
var s = new System.Text.StringBuilder();
using (var w = new System.IO.StringWriter(s))
using (var writer = new JsonTextWriter(w)
{Formatting = Formatting.Indented})
{
var serializer = JsonSerializer.Create(serializerSettings);
serializer.Serialize(writer, dynamicObject);
writer.Flush();
}
Console.WriteLine(s.ToString());
}
}
The ISO 8601 format allows for many variations of dates and times, to arbitrary precision. From Wikipedia's article on ISO 8601:
There is no limit on the number of decimal places for the decimal fraction. However, the number of decimal places needs to be agreed to by the communicating parties.