2014-01-09 1 views
17

Что такое идиоматический способ получить время системы как LocalDateTime в Noda Time? Самый прямой метод, который я мог думать, был быПолучение LocalDateTime системы в Noda Time

var dt = DateTime.Now 
LocalDateTime systemTime = new LocalDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute); 

, но при условии, что Нод Время entire purpose is to replace DateTime with something that has nicer semantics, я предположил, был предпочтительный метод, чем использовать DateTime вышеуказанного способа. Лучшее, что я мог придумать с использованием средств Ноды, - это

var zone = NodaTime.TimeZones.BclDateTimeZone.ForSystemDefault(); 
LocalDateTime systemTime = SystemClock.Instance.Now.InZone(zone).LocalDateTime; 

но это кажется довольно многословным.

ответ

31

Ваш второй пример - именно то, как вы это сделаете. Это намеренно подробный. См. Noda Time's design philosophy.

Думать об этом в трех частях:

  1. Получить текущий момент времени:

    // Instant now = SystemClock.Instance.Now;    // NodaTime 1.x 
    Instant now = SystemClock.Instance.GetCurrentInstant(); // NodaTime 2.x 
    
  2. Получить часовой пояс системы. (Это предпочтительный синтаксис)

    DateTimeZone tz = DateTimeZoneProviders.Bcl.GetSystemDefault(); 
    
  3. Нанести часовой пояс момент:

    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 во время ваших модульных тестов. См. Unit Testing with Noda Time для более подробной информации.

  • Вы также можете перейти в DateTimeZone, чтобы вы могли запускать свой код в любом месте, не привязавшись к системному часовому поясу. Это важно для серверных приложений, но тем более для настольных/мобильных приложений.

  • Если у вас есть другая работа, которая с использованием часовых поясов IANA, а затем изменить шаг 2, чтобы использовать этот поставщик:

    DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault(); 
    

    В TZDB зоны гораздо более точны, чем BCL зон. Noda Time отобразит часовой пояс вашей системы Windows (BCL) в часовом поясе IANA (TZDB) в этом первоначальном вызове.

Если у вас есть любопытство в почему DateTime.Now настолько компактно, в то время как Нод время так многословно, попробуйте декомпиляцию DateTime.Now или глядя на эталонные источниках MS. Вы увидите, что он выполняет те же действия под капотом.

+0

Спасибо за такой глубокий и информативный ответ! Re: дополнительные очки, я планирую вместо инъекции IClock. Кроме того, я хочу использовать системное время здесь. Код предназначен для техников, которые будут использовать в поле, чтобы установить время на микроконтроллере, который «слишком тупой», чтобы иметь концепцию часового пояса. Однако я использую Noda Time, потому что одна и та же библиотека также будет использоваться на нашем сервере для связи с устройствами по беспроводной сети после их настройки. –

+0

Я сделал что-то подобное не так давно. В моем случае было более целесообразно связать каждое устройство с определенным часовым поясом, а не использовать часовой пояс машины, с которой они разговаривали. YMMV. –

+0

Кроме того, вам может потребоваться подумать о том, как обращаться с изменениями DST на вашем устройстве. Это была другая область, с которой мне пришлось сосредоточиться на этом проекте. –

 Смежные вопросы

  • Нет связанных вопросов^_^