Ответ 1
Бесстыдный штекер:
Использовать лучший API с датой и временем
Встроенные библиотеки даты и времени .NET ужасно трудны в использовании. Они позволяют вам делать все, что вам нужно, но вы не можете четко выразить себя через систему типов. DateTime
является беспорядком, DateTimeOffset
может усыпить вас мыслью, что вы фактически сохраняете информацию о часовом поясе, когда вы этого не сделали, и TimeZoneInfo
не заставляет вас думать обо всем, что вы должны учитывать.
Ни один из них не дает хороший способ сказать "просто время суток" или "просто дату" и не проводить четкое различие между "местным временем" и "временем в конкретном часовом поясе". И если вы хотите использовать календарь, отличный от григорианского, вам нужно все время проходить через класс Calendar
.
Все это почему я строю Noda Time - альтернативная библиотека даты и времени, построенная на порту Joda Time "движок", но с новым (и более компактным) API сверху.
Некоторые моменты, о которых вы можете подумать, которые легко пропустить, если вы не знаете о них:
- Сопоставление локальной даты/времени с одним в конкретном часовом поясе не так просто, как вы могли бы подумать. Конкретная локальная дата/время может возникать один раз, дважды (двусмысленность) или нулевое время (оно пропускается) из-за перехода на летнее время.
- Временные зоны меняются исторически - более чем
TimeZoneInfo
, как правило, охотно раскрывает, честно говоря. (Он не поддерживает часовой пояс, чья идея "стандартного времени" изменяется со временем или которая переходит в постоянное летнее время.) - Даже в базе данных zoneinfo идентификаторы часовых поясов не обязательно стабильны. (CLDR адресует это, то, что я надеюсь поддержать в Нода-Времени в конце концов.)
- Текстовые представления дат и времени - это кошмар, а не только с точки зрения заказа, но разделители дат, разделители времени и нечетные вещи, такие как имена родительного месяца.
- Начало дня - не всегда полночь - в Бразилии, например, переход на летнее время spring перемещает настенные часы с 11:59:59 вечера до 1 часа.
- В некоторых случаях (ну, я знаю) часовой пояс может заставить пропустить целый день - 30 декабря 2011 года не произошло на Самоа! Я подозреваю, что большинство разработчиков могут игнорировать этот, но...
- Если вы собираетесь использовать календарь, отличный от григорианского, будьте осторожны и убедитесь, что вы действительно знаете, как вы ожидаете, что он будет себя вести.
Что касается конкретных методов разработки:
- Подумайте о том, что вы действительно пытаетесь представить. Я ожидаю, что основное преимущество Noda Time будет заставлять разработчиков выбирать между различными типами для представления своих данных. Получите это правильно, и все остальное проще.
- Unit test все, что вы можете придумать. Конечно, это будет зависеть от того, что делает ваша система, но, в частности, учитывать разные часовые пояса, что происходит в переходных периодах перехода на летнее время и, конечно, в високосные годы.
- Я бы посоветовал вводить "тактико-подобный интерфейс" - службу для указания текущего времени - вместо явного вызова
DateTime.Now
илиDateTime.UtcNow
; это упрощает (возможно!) до unit test - Если вы выполняете несколько операций с "сейчас", получите эту дату/время один раз и запомните это, а не повторно запрашивая "сейчас" - в противном случае значение может измениться неудачными способами между вызовами.
- "Делать все в UTC" не всегда является ответом - если я хочу знать ", когда именно" через две недели "происходит в моем местном часовом поясе?" то мне нужно сохранить локальную дату/время, а также часовой пояс.