Как глобально сериализовать и десериализовать Date против DateTime при хранении в формате UTC? - PullRequest
0 голосов
/ 24 ноября 2018

В моей базе данных SQL Server я храню все значения DateTime как UTC.Однако в некоторых случаях меня не волнует время, например, когда пользователь в некотором случайном часовом поясе выбирает дату с помощью DatePicker.В этих случаях, казалось бы, имеет смысл просто сохранить как Date против DateTime.

. При извлечении дат из базы данных и их отправке в мое приложение Angular через Web API, я хотелчтобы все мои значения DateTime были отформатированы таким образом, чтобы Angular узнал, что это даты в формате UTC, и отображается как местное время, поэтому я добавил это в Web API, чтобы добавить "Z" в конце:

// Set all dates to UTC
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter
{
    DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
});

Это работает, но проблема в том, что это преобразование также применяется к моим Date значениям.Когда дата извлекается из базы данных в C #, они находятся в переменных DateTime, поскольку в C # нет переменной Date, поэтому они получают время полуночи.Таким образом, если пользователь в CST выбирает дату 24.11.08, когда он совершает обратную поездку в базу данных и обратно, он становится 23.11.2008 (с усеченным временем в 18:00).

Как я могу предотвратить это поведение?Вот некоторые идеи:

  1. Условно применить IsoDateTimeConverter?
    • Я не думаю, что это возможно в глобальном масштабе, поскольку я не смог бы определить, было ли это значение Date или DateTime, сохраненное в переменной C # DateTime.
  2. Изменить тип данных в SQL Server на DateTime?
    • Не думаю, что это тоже сработает, потому что даже если бы я хранил время в зависимости от места происхождения данных, разве оно не могло быть неправильным для пользователей в других часовых поясах?

1 Ответ

0 голосов
/ 25 ноября 2018

Используя предложение @ John, я создал собственный IsoDateTimeConverter:

public class DateConverter : IsoDateTimeConverter
{
    public DateConverter()
    {
        DateTimeFormat = "MM-dd-yyyy";
    }
}

и вручную применил его к каждому значению Date, которое переопределяет глобальный конвертер, добавленный в конфигурацию Web API.

[JsonConverter(typeof(DateConverter))]
public System.DateTime StartDate { get; set; }

Я все еще надеюсь, что есть глобальный способ справиться с этим, вместо того, чтобы применять атрибут к каждому свойству Date, но это по крайней мере отвлекает меня.

A предупреждение для пользователей Angular.Первоначально я пытался использовать формат «гггг-ММ-дд», но он должен интерпретировать это как UTC, потому что у меня была та же проблема, когда дата была показана пользователю.Изменение его на «ММ-дд-гггг» сработало.См https://github.com/angular/material2/issues/6111

...