CSharp · Console
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Collections.ObjectModel;
using System.Reflection;
using System.ComponentModel;
using System.Globalization;
using System.Web.Routing;
using System.Net.Mail;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Net;
using System.Numerics;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
// https://stackoverflow.com/questions/41980863/json-to-net-epoch-date-conversion
public class MicrosoftSecondsDateTimeConverter : DateTimeConverterBase
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var token = JToken.Load(reader);
if (token.Type == JTokenType.String)
{
var s = ((string)token).Trim();
if (s.StartsWith("/Date(", StringComparison.Ordinal) && s.EndsWith(")/", StringComparison.Ordinal))
{
// MS datetime format is in milliseconds as is shown here:
// https://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_sidebarb
// But our times are offsets in seconds.
// Convert.
var sb = new StringBuilder("\"\\/Date(");
var insert = "000"; // Seconds to MS
for (int i = 6; i < s.Length - 2; i++)
{
if (s[i] == '-' || s[i] == '+') // Time zone marker
{
sb.Append(insert);
insert = string.Empty;
}
sb.Append(s[i]);
}
sb.Append(insert);
sb.Append(")\\/\"");
s = sb.ToString();
var dt = new JsonSerializer().Deserialize(new StringReader(s), objectType);
return dt;
}
}
// Not a Microsoft date.
return new JsonSerializer().Deserialize(token.CreateReader(), objectType);
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public class DateParseHandlingConverter : JsonConverter
{
// Taken from https://stackoverflow.com/questions/40632820/how-to-prevent-a-single-object-property-from-being-converted-to-a-datetime-when
readonly DateParseHandling dateParseHandling;
public DateParseHandlingConverter(DateParseHandling dateParseHandling)
{
this.dateParseHandling = dateParseHandling;
}
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var old = reader.DateParseHandling;
try
{
reader.DateParseHandling = dateParseHandling;
existingValue = existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
serializer.Populate(reader, existingValue);
return existingValue;
}
finally
{
reader.DateParseHandling = old;
}
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
[JsonConverter(typeof(DateParseHandlingConverter), DateParseHandling.None)] // Disable Json.NET's built-in date time parsing function.
public class RootObject
{
[JsonConverter(typeof(MicrosoftSecondsDateTimeConverter))]
public DateTime pickupBefore { get; set; }
}
public class TestClass
{
public static void Test()
{
Test(@"{""pickupBefore"":""/Date(1485360480-0800)/""}");
Console.WriteLine("");
// Ensure ISO dates still work.
Test(@"{""pickupBefore"":""2017-01-25T11:08:00-05:00""}");
}
private static void Test(string json)
{
Console.WriteLine("Testing JSON: " + json);
var root = JsonConvert.DeserializeObject<RootObject>(json);
Assert.IsTrue(root.pickupBefore.Year == 2017);
Console.WriteLine("root.pickupBefore.Year == 2017");
Console.WriteLine("Reserialized JSON: ");
Console.WriteLine(JsonConvert.SerializeObject(root));
Console.WriteLine(JsonConvert.SerializeObject(root, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }));
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("");
TestClass.Test();
}
}
public class AssertionFailedException : System.Exception
{
public AssertionFailedException() : base() { }
public AssertionFailedException(string s) : base(s) { }
}
public static class Assert
{
public static void IsTrue(bool value)
{
if (value == false)
throw new AssertionFailedException("failed");
}
}