feat: Better handling of JSON DateTimes in Net Standard

This commit is contained in:
Chris Cameron
2019-08-27 15:01:09 -04:00
parent f33218f7a6
commit 18abe78550
4 changed files with 44 additions and 89 deletions

View File

@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Changed
- Fixed a bug where ANSI color encoded strings with percentages were being scrambled
- Improvements to JSON DateTime parsing, particularly in Net Standard
## [9.7.0] - 2019-08-15
### Added

View File

@@ -10,29 +10,7 @@ namespace ICD.Common.Utils.Tests.Json
public sealed class JsonUtilsTest
{
[Test]
public void CacheTypeTest()
{
Assert.Inconclusive();
}
[Test]
public void ParseDateTimeTest()
{
const string dataA = "2016-02-26T19:24:59";
const string dataB = "2019-04-01T12:41:15-04:00";
Assert.DoesNotThrow(() => JsonUtils.ParseDateTime(dataA));
Assert.DoesNotThrow(() => JsonUtils.ParseDateTime(dataB));
}
[Test]
public void TryParseDateTimeTest()
{
Assert.Inconclusive();
}
[Test]
public void PrintTest()
public void FormatTest()
{
Assert.Inconclusive();
}

View File

@@ -1,6 +1,5 @@
using System;
using ICD.Common.Properties;
using ICD.Common.Utils.Json;
using Newtonsoft.Json;
namespace ICD.Common.Utils.Extensions
@@ -21,7 +20,12 @@ namespace ICD.Common.Utils.Extensions
if (extends == null)
throw new ArgumentNullException("extends");
JsonSerializer serializer = new JsonSerializer();
JsonSerializer serializer =
#if SIMPLSHARP
new JsonSerializer();
#else
JsonSerializer.CreateDefault();
#endif
return extends.ReadAsObject<T>(serializer);
}
@@ -145,7 +149,13 @@ namespace ICD.Common.Utils.Extensions
{
if (extends == null)
throw new ArgumentNullException("extends");
#if !SIMPLSHARP
// Newer versions of NewtonSoft try to be helpful and interpret strings as DateTimes without any consideration for different DateTime formats.
if (extends.TokenType == JsonToken.Date && extends.DateParseHandling != DateParseHandling.None)
throw new InvalidOperationException("DateParseHandling needs to be set to None");
#endif
if (!extends.TokenType.IsPrimitive())
throw new FormatException("Expected primitive token type but got " + extends.TokenType);
@@ -213,12 +223,36 @@ namespace ICD.Common.Utils.Extensions
if (extends == null)
throw new ArgumentNullException("extends");
#if SIMPLSHARP
string stringValue = extends.GetValueAsString();
return JsonUtils.ParseDateTime(stringValue);
#else
return (DateTime)extends.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)
return (DateTime)extends.Value;
#endif
string stringValue = extends.GetValueAsString();
return DateTime.Parse(stringValue);
}
/// <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(this JsonReader extends, string format, IFormatProvider provider)
{
if (extends == null)
throw new ArgumentNullException("extends");
#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);
}
}
}

View File

@@ -5,7 +5,6 @@ using ICD.Common.Properties;
using ICD.Common.Utils.Extensions;
using ICD.Common.Utils.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace ICD.Common.Utils.Json
{
@@ -18,63 +17,6 @@ namespace ICD.Common.Utils.Json
private const string MESSAGE_NAME_PROPERTY = "m";
private const string MESSAGE_DATA_PROPERTY = "d";
/// <summary>
/// Gets the data as a DateTime value.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static DateTime ParseDateTime(string data)
{
return DateTime.Parse(data);
}
/// <summary>
/// Gets the token as a DateTime value.
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
[PublicAPI]
public static DateTime ParseDateTime(JToken token)
{
if (token == null)
throw new ArgumentNullException("token");
#if SIMPLSHARP
return ParseDateTime((string)token);
#else
return (DateTime)token;
#endif
}
/// <summary>
/// Gets the token as a DateTime value.
/// </summary>
/// <param name="token"></param>
/// <param name="output"></param>
/// <returns></returns>
[PublicAPI]
public static bool TryParseDateTime(JToken token, out DateTime output)
{
if (token == null)
throw new ArgumentNullException("token");
output = default(DateTime);
try
{
output = ParseDateTime(token);
return true;
}
catch (FormatException)
{
return false;
}
catch (InvalidCastException)
{
return false;
}
}
/// <summary>
/// Serializes the given item and formats the JSON into a human-readable form.
/// </summary>