using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; namespace ROLAC.API.Json; /// /// Reads 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. /// public sealed class TolerantDateOnlyConverter : JsonConverter { 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)); }