Лучшие практики сериализации DateTime в .NET 3.5

Примерно 4 года назад я следовал рекомендациям по использованию Статья MSDN для DateTime для создания клиента .Net на веб-сервисах .Net 1.1 и ASMX (с сервером SQL 2000 в качестве бэкэнда). Я до сих пор помню проблемы сериализации, которые у меня были с DateTime, и усилия по тестированию серверов в разных часовых поясах.

Мои вопросы таковы: существует ли аналогичный документ с лучшими практиками для некоторых новых технологий, таких как WCF и SQL server 2008, особенно с добавлением новых типов datetime для хранения информации о часовом поясе.

Это среда:

  1. SQL server 2008 по тихоокеанскому времени.
  2. Слой веб-служб в другом часовом поясе.
  3. Клиенты могут использовать .Net 2.0 или .Net 3.5 в разных часовых поясах. Если это упростит, мы можем заставить всех перейти на .Net 3.5. :)

Любые хорошие предложения / лучшие практики для типов данных, которые будут использоваться на каждом уровне?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
22
0
47 068
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Я думаю, что лучший способ сделать это - всегда передавать объект как UTC и конвертировать в местное время на клиентах. Таким образом, все клиенты получают общую точку отсчета.

Чтобы преобразовать в UTC, вызовите ToUniversalTime для объекта DateTime. Затем на клиентах вызовите ToLocalTime, чтобы получить его в их текущем часовом поясе.

Обратите внимание, что клиент получит тип datetime как Unspecified. Когда вы вызываете на нем ToUniversalTime, он будет предполагатьLocal time и фактически выполнит преобразование. Правильный способ - использовать DateTime.SpecifyKind(myUtcTime, DateTimeKind.Utc) вместо ToUniversalTime.

Eren Ersönmez 06.08.2015 10:17

Мне повезло, что я просто сохранил тип данных DateTime и всегда сохранял его как GMT. В каждом слое я бы настроил значение GMT ​​на локальное значение для слоя.

Пока ваш уровень веб-сервисов и уровень клиента используют тип .NET DateTime, он должен правильно сериализоваться и десериализоваться как стандартная локальная дата / время SOAP с информацией о часовом поясе, например:

2008-09-15T13: 14: 36.9502109-05: 00

Если вы абсолютно точно должны знать сам часовой пояс (т.е.вышеупомянутое может быть восточно-стандартное время или центральное летнее время), вам необходимо создать свой собственный тип данных, который представляет эти части как таковые:

[Serializable]
public sealed class MyDateTime
{
    public MyDateTime()
    {
        this.Now = DateTime.Now;
        this.IsDaylightSavingTime = this.Now.IsDaylightSavingTime();
        this.TimeZone = this.IsDaylightSavingTime
            ? System.TimeZone.CurrentTimeZone.DaylightName
            : System.TimeZone.CurrentTimeZone.StandardName;
    }

    public DateTime Now
    {
        get;

        set;
    }

    public string TimeZone
    {
        get;

        set;
    }

    public bool IsDaylightSavingTime
    {
        get;

        set;
    }
}

тогда ваш ответ будет выглядеть так:

<Now>2008-09-15T13:34:08.0039447-05:00</Now>
<TimeZone>Central Daylight Time</TimeZone>
<IsDaylightSavingTime>true</IsDaylightSavingTime>

Вот как теперь работает WCF. Я не получаю ничего с указанием часового пояса (например, -05: 00).

Piotr Owsiak 08.01.2010 21:57

UTC / GMT будет согласованным в распределенной среде.

Важным моментом является указание datetimeKind после заполнения вашего свойства DateTime значением из базы данных.

dateTimeValueUtcKind = DateTime.SpecifyKind(dateTimeValue, DateTimeKind.Utc);

См. MSDN

Одна большая проблема заключается в том, что сериализация WCF не поддерживает xs: Date. Это большая проблема, так как если все, что вам нужно, это свидание, вам не следует беспокоиться о часовых поясах. В следующей проблеме подключения обсуждаются некоторые из проблем: http://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=349215

Если вы хотите однозначно представить момент времени, то есть не только дату, вы можете использовать класс DateTimeOffset, если у вас есть .NET 3.5 как на клиенте, так и на сервере. Или для обеспечения совместимости всегда передавайте значения даты и времени в формате UTC.

Если вы хотите использовать DateTimeOffset и WCF, эти две статьи могут быть полезны при возникновении проблем с сериализацией: msdn.microsoft.com/en-us/library/ms730167(v=VS.90).aspxblogs.msdn.com/b/drnick/archive/2008/09/04/…

Perhentian 21.09.2011 17:14

по состоянию на 28.03.2013 ссылка в посте Джо не работает.

Zack Jannsen 28.03.2013 17:27

В случаях, когда объект datetime должен оставаться неизменным, используйте JsonConvert:

DateTime now = DateTime.Now;
string json = JsonConvert.SerializeObject(now);
DateTime nowJson = JsonConvert.DeserializeObject<DateTime>(json);

Другие вопросы по теме