Лучшие практики для сериализации DateTime в .NET 3.5 - PullRequest
21 голосов
/ 15 сентября 2008

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

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

Это среда:

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

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

Ответы [ 5 ]

18 голосов
/ 15 сентября 2008

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

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

12 голосов
/ 17 сентября 2008

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

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

4 голосов
/ 16 сентября 2008

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

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

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

См. MSDN

2 голосов
/ 15 сентября 2008

Пока ваш слой веб-сервисов и уровень клиента используют тип .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>
1 голос
/ 15 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...