feat: Serializing JSON DateTimes to ISO-8601

This commit is contained in:
Chris Cameron
2020-05-22 17:55:18 -04:00
parent 582cbe9157
commit 7053faede1
5 changed files with 97 additions and 1 deletions

View File

@@ -116,6 +116,16 @@ namespace ICD.Common.Utils.Extensions
return extends.StartOfDay() + new TimeSpan(24, 0, 0);
}
/// <summary>
/// Returns the give date in ISO-8601 format.
/// </summary>
/// <param name="extends"></param>
/// <returns></returns>
public static string ToIso(this DateTime extends)
{
return extends.ToString("o");
}
/// <summary>
/// Returns the given date in unix timestamp format.
/// </summary>

View File

@@ -69,7 +69,7 @@ namespace ICD.Common.Utils.Extensions
throw new ArgumentNullException("extends");
extends.WritePropertyName(propertyName);
extends.WriteValue(value);
extends.WriteValue(value.ToIso());
}
/// <summary>

View File

@@ -131,6 +131,7 @@
<Compile Include="IO\IcdBinaryReader.cs" />
<Compile Include="IO\eSeekOrigin.cs" />
<Compile Include="IO\IcdStreamWriter.cs" />
<Compile Include="Json\DateTimeIsoConverter.cs" />
<Compile Include="Json\ToStringJsonConverter.cs" />
<Compile Include="NullObject.cs" />
<Compile Include="ProcessorUtils.SimplSharp.cs" />

View File

@@ -0,0 +1,58 @@
using System;
using System.Text.RegularExpressions;
using ICD.Common.Utils.Extensions;
using Newtonsoft.Json;
namespace ICD.Common.Utils.Json
{
public sealed class DateTimeIsoConverter : AbstractGenericJsonConverter<DateTime>
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
{
writer.WriteValue(value.ToIso());
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>
/// The object value.
/// </returns>
public override DateTime ReadJson(JsonReader reader, DateTime existingValue, JsonSerializer serializer)
{
/*
"\"\\/Date(1335205592410)\\/\"" .NET JavaScriptSerializer
"\"\\/Date(1335205592410-0500)\\/\"" .NET DataContractJsonSerializer
"2012-04-23T18:25:43.511Z" JavaScript built-in JSON object
"2012-04-21T18:25:43-05:00" ISO 8601
*/
string serial = reader.GetValueAsString();
Match match;
if (RegexUtils.Matches(serial, @"Date\((?'date'\d+)(?'zone'(-|\+)\d+)?\)", out match))
{
long ms = long.Parse(match.Groups["date"].Value);
DateTime dateTime = DateTimeUtils.FromEpochMilliseconds(ms);
if (!match.Groups["zone"].Success)
return dateTime;
// No TimeZoneInfo in CF, so now things get gross
dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified);
string iso = dateTime.ToIso() + match.Groups["zone"].Value;
return DateTime.Parse(iso);
}
return DateTime.Parse(serial);
}
}
}

View File

@@ -17,6 +17,33 @@ namespace ICD.Common.Utils.Json
private const string MESSAGE_NAME_PROPERTY = "m";
private const string MESSAGE_DATA_PROPERTY = "d";
private static JsonSerializerSettings s_CommonSettings;
/// <summary>
/// Gets the common JSON serializer settings for cross-platform support.
/// </summary>
public static JsonSerializerSettings CommonSettings
{
get
{
if (s_CommonSettings != null)
return s_CommonSettings;
s_CommonSettings = new JsonSerializerSettings
{
#if !SIMPLSHARP
// Turn off the ridiculous new behaviour of DateTiming anything vaguely resembling a date
DateParseHandling = DateParseHandling.None,
#endif
};
// Serialize DateTimes to ISO
s_CommonSettings.Converters.Add(new DateTimeIsoConverter());
return s_CommonSettings;
}
}
/// <summary>
/// Serializes the given item and formats the JSON into a human-readable form.
/// </summary>