Дата и время с учетом поясов – DateTimeOffset

пятница, 19 ноября 2010, Роман Калита

Все мы очень часто пользуемся такой структурой из BCL как DateTime. Но если необходимо учитывать время в разных часовых поясах то, начиная с .NET 3.5 в BCL появилась новая структура DateTimeOffset.

Но многие приложения или их части должны работать в разных часовых поясах. Чтобы учесть часовые пояса в DateTime необходимо внешне конвертировать время из одного значения в другое создав либо метод для конвертации, либо враппер вокруг DateTime, наследоваться же от него не получится, так как это структура. Вот именно DateTimeOffset и решает эту проблему. Фактически это тот же DateTime только с возможностью установить смещение часового пояса.


Разница между ними видна невооруженным глазом, если взглянуть на результат работы следующих двух строчек кода:

Console.WriteLine(DateTime.Now);
Console.WriteLine(DateTimeOffset.Now);
image

DateTimeOffset совместим с DateTime, и значение между ними можно легко конвертировать.

DateTime в DateTimeOffset :

DateTime d1 = DateTime.Now;
DateTimeOffset o1 = new DateTimeOffset(d1);
DateTimeOffset of1 = new DateTimeOffset(d1, new TimeSpan(-5, 0, 0));
Например DateTimeOffset в DateTime:
DateTimeOffset o2 = DateTimeOffset.Now;
DateTime d2 = o2.DateTime;
Можно также вручную задать значения:
DateTime dt1 = new DateTime(2008, 8, 22, 1, 0, 0);
DateTimeOffset do1 = new DateTimeOffset(2008, 8, 22, 1, 0, 0, new TimeSpan(-5, 0, 0));
Или производить над ними арифметические действия
DateTime dateTime1 = DateTime.Now;
DateTime dateTime2 = DateTime.UtcNow;
Console.WriteLine(dateTime1 - dateTime2);

DateTimeOffset offset1 = DateTimeOffset.Now;
DateTimeOffset offset2 = DateTimeOffset.UtcNow;
Console.WriteLine(offset1 - offset2);
С DateTimeOffset легко сравнивать значения времени в разных часовых поясах. Например код ниже сравнивает разные на первый взгляд значения в разных часовых поясах. Но результат будет true. Так как в UTC их значение будет одинаковым:
DateTimeOffset ao1 = new DateTimeOffset(2008, 8, 22, 12, 0, 0, new TimeSpan(-5, 0, 0));
DateTimeOffset ao2 = new DateTimeOffset(2008, 8, 22, 9, 0, 0, new TimeSpan(-8, 0, 0));
Console.WriteLine(ao1 == ao2);

Когда же лучше использовать DateTime, а когда DateTimeOffset?

Можно выделить такие сценарии использования:

  • DateTimeOffset лучше использовать для значений даты, когда их смещение относительно UTC, т.е. часовой пояс, известны или когда необходимо производить операции с датами из разных часовых поясов. Но это не значит, что необходимо полностью отказаться от DateTime в пользу его аналога со смещением.
  • DateTime удобно использовать, когда нет привязки к часовым поясам либо часовой пояс не известен, т.е. просто представить значение даты, например время открытия магазинов
  • Также DateTime больше подходит для хранения значений из БД(в SQL Server 2008 есть datetimeoffset) так как в большинстве СУБД не хранится информация о часовом поясе.
  • DateTime более подходит для interop сценариев, например OLE Automation, databases, существующее .NET API, где используется DateTime и т.п.
  • DateTime с временем 00:00:00 чтобы представить дату, например День рождения
  • TimeSpan для указания времени без даты

Ребята из команды BCL пишут DateTimeOffset is the new preferred type to use for the most common date time scenarios.


Ищите нас в интернетах!

Комментарии

Свежие вакансии