refactor: JSON DateTime cleanup

This commit is contained in:
Chris Cameron
2020-05-28 13:46:49 -04:00
parent 25fb5a0ad8
commit 4339f02698
5 changed files with 54 additions and 60 deletions

View File

@@ -1,4 +1,5 @@
using System;
using System.Globalization;
namespace ICD.Common.Utils
{
@@ -33,5 +34,15 @@ namespace ICD.Common.Utils
{
return FromEpochMilliseconds(seconds * 1000);
}
/// <summary>
/// Returns a DateTime for the given ISO-8601 string.
/// </summary>
/// <param name="iso"></param>
/// <returns></returns>
public static DateTime FromIso8601(string iso)
{
return DateTime.Parse(iso, null, DateTimeStyles.RoundtripKind);
}
}
}

View File

@@ -1,5 +1,5 @@
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using ICD.Common.Properties;
using Newtonsoft.Json;
@@ -271,35 +271,29 @@ namespace ICD.Common.Utils.Extensions
if (extends.DateParseHandling != DateParseHandling.None)
return (DateTime)extends.Value;
#endif
/*
"\"\\/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 stringValue = extends.GetValueAsString();
return DateTime.Parse(stringValue, null, DateTimeStyles.RoundtripKind);
}
string serial = extends.GetValueAsString();
/// <summary>
/// Gets the current value as a date.
/// </summary>
/// <param name="extends"></param>
/// <param name="format"></param>
/// <param name="provider"></param>
/// <returns></returns>
public static DateTime GetValueAsDateTimeExact([NotNull] this JsonReader extends, [NotNull] string format,
IFormatProvider provider)
Match match;
if (RegexUtils.Matches(serial, @"Date\((?'date'\d+)(?'zone'(-|\+)\d+)?\)", out match))
{
if (extends == null)
throw new ArgumentNullException("extends");
long ms = long.Parse(match.Groups["date"].Value);
DateTime dateTime = DateTimeUtils.FromEpochMilliseconds(ms);
if (!match.Groups["zone"].Success)
return dateTime;
if (format == null)
throw new ArgumentNullException("format");
// No TimeZoneInfo in CF, so now things get gross
dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified);
serial = dateTime.ToIso() + match.Groups["zone"].Value;
}
#if !SIMPLSHARP
// Newer NewtonSoft tries to be helpful by assuming that anything that looks like a DateTime must be a date.
if (extends.DateParseHandling != DateParseHandling.None)
throw new InvalidOperationException("DateParseHandling needs to be set to None");
#endif
string stringValue = extends.GetValueAsString();
return DateTime.ParseExact(stringValue, format, provider);
return DateTimeUtils.FromIso8601(serial);
}
}
}

View File

@@ -6,6 +6,24 @@ namespace ICD.Common.Utils.Extensions
{
public static class JsonWriterExtensions
{
/// <summary>
/// Writes the DateTime as an ISO-8601 string.
/// </summary>
/// <param name="extends"></param>
/// <param name="dateTime"></param>
public static void WriteDateTime([NotNull] this JsonWriter extends, DateTime dateTime)
{
if (extends == null)
throw new ArgumentNullException("extends");
string iso = dateTime.ToIso();
// Remove redundant ms
iso = iso.Replace(".0000000", "");
extends.WriteValue(iso);
}
/// <summary>
/// Writes the type value.
/// </summary>
@@ -69,7 +87,7 @@ namespace ICD.Common.Utils.Extensions
throw new ArgumentNullException("extends");
extends.WritePropertyName(propertyName);
extends.WriteValue(value.ToIso());
extends.WriteDateTime(value);
}
/// <summary>

View File

@@ -1,6 +1,4 @@
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using ICD.Common.Utils.Extensions;
using Newtonsoft.Json;
@@ -16,12 +14,7 @@ namespace ICD.Common.Utils.Json
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
{
string iso = value.ToIso();
// Remove redundant ms
iso = iso.Replace(".0000000", "");
writer.WriteValue(iso);
writer.WriteDateTime(value);
}
/// <summary>
@@ -35,29 +28,7 @@ namespace ICD.Common.Utils.Json
/// </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);
serial = dateTime.ToIso() + match.Groups["zone"].Value;
}
return DateTime.Parse(serial, null, DateTimeStyles.RoundtripKind);
return reader.GetValueAsDateTime();
}
}
}

View File

@@ -52,7 +52,7 @@ namespace ICD.Common.Utils.Json
[PublicAPI]
public static string Format(object value)
{
string serial = JsonConvert.SerializeObject(value);
string serial = JsonConvert.SerializeObject(value, Formatting.None, CommonSettings);
return Format(serial);
}