34 lines
1.3 KiB
C#
34 lines
1.3 KiB
C#
using System.Globalization;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace ROLAC.API.Json;
|
|
|
|
/// <summary>
|
|
/// Reads <see cref="DateOnly"/> from either "yyyy-MM-dd" or any ISO 8601 date-time
|
|
/// (the date portion is taken). Writes as "yyyy-MM-dd". Lets JS clients send a Date
|
|
/// without first formatting it.
|
|
/// </summary>
|
|
public sealed class TolerantDateOnlyConverter : JsonConverter<DateOnly>
|
|
{
|
|
private const string Format = "yyyy-MM-dd";
|
|
|
|
public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
{
|
|
var s = reader.GetString();
|
|
if (string.IsNullOrEmpty(s))
|
|
throw new JsonException("Expected a date string for DateOnly.");
|
|
|
|
if (DateOnly.TryParseExact(s, Format, CultureInfo.InvariantCulture, DateTimeStyles.None, out var d))
|
|
return d;
|
|
|
|
if (DateTimeOffset.TryParse(s, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dto))
|
|
return DateOnly.FromDateTime(dto.DateTime);
|
|
|
|
throw new JsonException($"Unable to parse '{s}' as DateOnly.");
|
|
}
|
|
|
|
public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
|
|
=> writer.WriteStringValue(value.ToString(Format, CultureInfo.InvariantCulture));
|
|
}
|