System.Text.Json fails to deserialize ASP.NET JSON dates such as "/Date(1530144000000+0530)/" which seems silly as there are still microsoft apis using this date format. specifically the O365 Service Health Api.
We made a conscious decision to not support this non-standard format. You can, however use a custom converter to add your own support for this:
```c#
class Program
{
static void Main(string[] args)
{
var opts = new JsonSerializerOptions();
opts.Converters.Add(new FunnyDateConverter());
string json = JsonSerializer.Serialize(new
{
Date = DateTimeOffset.Now
}, options: opts);
Console.WriteLine(json);
}
}
sealed class FunnyDateConverter : JsonConverter
{
static readonly DateTimeOffset s_epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
static readonly Regex s_regex = new Regex("^/Date\(([^+-]+)([+-])(\d{2})(\d{2})\)/$", RegexOptions.CultureInvariant);
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (typeToConvert != typeof(DateTimeOffset))
{
throw new ArgumentException($"Unexpected type '{typeToConvert}'.");
}
string formatted = reader.GetString();
Match match = s_regex.Match(formatted);
if (
!match.Success
|| !long.TryParse(match.Groups[1].Value, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out long unixTime)
|| !int.TryParse(match.Groups[3].Value, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out int hours)
|| !int.TryParse(match.Groups[4].Value, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out int minutes))
{
throw new Exception("Unexpected value format, unable to parse DateTimeOffset.");
}
int sign = match.Groups[2].Value[0] == '+' ? 1 : -1;
TimeSpan utcOffset = new TimeSpan(hours * sign, minutes * sign, 0);
return s_epoch.AddMilliseconds(unixTime).ToOffset(utcOffset);
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
{
long unixTime = Convert.ToInt64((value - s_epoch).TotalMilliseconds);
TimeSpan utcOffset = value.Offset;
string formatted = FormattableString.Invariant($"/Date({unixTime}{(utcOffset >= TimeSpan.Zero ? "+" : "-")}{utcOffset:hhmm})/");
writer.WriteStringValue(formatted);
}
}
```
cc @steveharter, @JamesNK
For anyone blocked by this, here's a NuGet package with a couple converters (JsonMicrosoftDateTimeConverter & JsonMicrosoftDateTimeOffsetConverter) based on the code posted above by @scalablecory: Macross.Json.Extensions
Supports DateTime, Nullable<DateTime>, DateTimeOffset, & Nullable<DateTimeOffset> types in the old /Date(...)/ Microsoft format.
Most helpful comment
For anyone blocked by this, here's a NuGet package with a couple converters (JsonMicrosoftDateTimeConverter & JsonMicrosoftDateTimeOffsetConverter) based on the code posted above by @scalablecory: Macross.Json.Extensions
Supports DateTime, Nullable<DateTime>, DateTimeOffset, & Nullable<DateTimeOffset> types in the old /Date(...)/ Microsoft format.