Получение системного LocalDateTime во времени Noda
Вопрос
Каков идиоматический способ получить системное время в качестве LocalDateTime
во времена Ноды?Самый прямой метод, который я мог бы придумать, был бы
var dt = DateTime.Now
LocalDateTime systemTime = new LocalDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute);
но, учитывая, что время Ноды вся цель состоит в том, чтобы заменить DateTime чем-то, что имеет более приятную семантику, я предположил, что существует более предпочтительный метод, чем использовать DateTime
вышеуказанным способом.Лучшее, что я смог придумать, используя возможности Noda, - это
var zone = NodaTime.TimeZones.BclDateTimeZone.ForSystemDefault();
LocalDateTime systemTime = SystemClock.Instance.Now.InZone(zone).LocalDateTime;
но это кажется довольно многословным.
Решение
Ваш второй пример - это именно то, как бы вы это сделали.Это намеренно многословный.Видеть Философия дизайна Noda Time.
Подумайте об этом в трех частях:
Получите текущий момент времени:
// Instant now = SystemClock.Instance.Now; // NodaTime 1.x Instant now = SystemClock.Instance.GetCurrentInstant(); // NodaTime 2.x
Получите часовой пояс системы.(Это предпочтительный синтаксис)
DateTimeZone tz = DateTimeZoneProviders.Bcl.GetSystemDefault();
Примените часовой пояс к текущему моменту:
ZonedDateTime zdt = now.InZone(tz);
Ваш последний шаг к получению LocalDateTime
это тривиально, но осознайте, что, когда вы это делаете, вы удаляете любую информацию о часовом поясе."Локальный" в NodaTime делает нет означает "локальный по отношению к компьютеру, на котором выполняется код".(Другими словами, это не похоже на DateTimeKind.Local
)
Дополнительные вещи, о которых стоит подумать:
Возможно, вы предпочтете абстрагировать часы, используя
IClock
интерфейс:IClock clock = SystemClock.Instance; // Instant now = clock.Now; // NodaTime 1.x Instant now = clock.GetCurrentInstant(); // NodaTime 2.x
Затем вы могли бы передать часы в качестве параметра метода или внедрить их в свой любимый фреймворк DI/IoC.(Autofac, Ninject, StructureMap, что угодно...).Преимущество в том, что тогда вы могли бы использовать
NodaTime.Testing.FakeClock
во время ваших модульных тестов.Видеть Модульное тестирование с использованием Noda Time для получения более подробной информации.Возможно, вы также предпочтете пройти в
DateTimeZone
таким образом, вы можете запускать свой код в любом месте, не привязываясь к системному часовому поясу.Это важно для серверных приложений, но в меньшей степени для настольных / мобильных приложений.Если у вас есть другая работа, в которой используются часовые пояса IANA, или если вы используете стандартную сборку .NET для Noda Time, измените шаг 2, чтобы использовать
Tzdb
поставщик:DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault();
Зоны TZDB гораздо более точны, чем зоны BCL.При этом первоначальном вызове Noda Time сопоставит часовой пояс вашей системы Windows (BCL) с часовым поясом IANA (TZDB).
Если вам интересно, почему DateTime.Now
это настолько компактно, в то время как время Noda настолько многословно, попробуйте декомпилировать DateTime.Now
или просматривая справочные источники MS.Вы увидите, что он выполняет, по сути, те же действия под капотом.