Как десериализовать дату и местное время? - PullRequest
1 голос
/ 08 февраля 2020

Я знаю, что даты должны храниться в UT C Время, а затем отображаться на основе конфигурации клиента с использованием таких библиотек, как «момент-час». Тем не менее, я пишу программное обеспечение для огромной организации с множеством устаревших систем. Это не их культура хранения даты как UT C. У них десятки баз данных и тысячи таблиц, ни одна из них не использует приложение UT C.

My Angular, которое отправляет данные в мой API в формате ISO. Мои контроллеры получают дату со свойством Kind равно DateTimeKind.Utc.

Я могу преобразовать дату в местное время следующим образом:

    public  static class DateTimeExtension
    {
        public static DateTime ToBrasiliaTime(this DateTime date)
        {
            if (date.Kind != DateTimeKind.Utc)
                return date;

            return TimeZoneInfo.ConvertTimeFromUtc(date, TimeZoneInfo.FindSystemTimeZoneById("E. South America Standard Time"));
        }
    }

Затем я могу использовать

customer.bithrDate = customer.bithrDate.ToBrasiliaTime();....
product.assemblyDate = product.assemblyDate .ToBrasiliaTime();....
order.shippingDate = order.shippingDate .ToBrasiliaTime();....

Но я не хочу называть это расширение снова и снова ... Можно ли реализовать Model Binder для работы с данными тела и применить мои расширения logi c?

Опять же, я знаю, что даты должны храниться в UT C Время , но дело не в этом.

1 Ответ

1 голос
/ 08 февраля 2020

Вот решение Newtonsoft. Json с использованием специального конвертера JSON. Предполагается, что ваша дата отправлена ​​как UT C.

public class LocalDateTimeConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.Value == null)
        {
            return null; // or DateTime.MinValue since its automatically converted anyway
        }  

        var date = DateTime.Parse(reader.Value.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
        return TimeZoneInfo.ConvertTimeFromUtc(date, TimeZoneInfo.FindSystemTimeZoneById("E. South America Standard Time"));
    }

    public override bool CanConvert(Type objectType)
    {
        return true; 
    }

    public override bool CanWrite
    {
        get { return true; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
} 

. Украсьте свойство DateTime в вашей модели с атрибутом JsonConverter. Это выглядело бы примерно так:

public class SomeClass
{
    [JsonConverter(typeof(LocalDateTimeConverter))]
    public DateTime date { get; set; }
}

Несмотря на то, что преобразователь возвращает нулевое значение, когда передается нулевое значение, этот метод все равно приведет к DateTime.MinValue, когда он будет преобразован в DateTime. Вам нужно изменить тип на nullable DateTime?, если вы на самом деле хотите вместо него null.

Попробуйте онлайн

...