2015-12-29 2 views
3

Может ли кто-нибудь дать мне самый простой способ создать ZonedDateTime, учитывая «4:30 вечера» и «Америка/Чикаго».Nodatime создать ZonedDateTime с учетом времени и времени

Я хочу, чтобы этот объект представлял это время для текущей даты в этом часовом поясе.

Спасибо!

Я пробовал это ... но, похоже, на самом деле дает мне мгновение в локальном часовом поясе, который получает смещение при создании zonedDateTime.

 string time = "4:30pm"; 
     string timezone = "America/Chicago"; 
     DateTime dateTime; 
     if (DateTime.TryParse(time, out dateTime)) 
     { 
      var instant = new Instant(dateTime.Ticks); 
      DateTimeZone tz = DateTimeZoneProviders.Tzdb[timezone]; 
      var zonedDateTime = instant.InZone(tz); 

ответ

7
using NodaTime; 
using NodaTime.Text; 

// your inputs 
string time = "4:30pm"; 
string timezone = "America/Chicago"; 

// parse the time string using Noda Time's pattern API 
LocalTimePattern pattern = LocalTimePattern.CreateWithCurrentCulture("h:mmtt"); 
ParseResult<LocalTime> parseResult = pattern.Parse(time); 
if (!parseResult.Success) { 
    // handle parse failure 
} 
LocalTime localTime = parseResult.Value; 

// get the current date in the target time zone 
DateTimeZone tz = DateTimeZoneProviders.Tzdb[timezone]; 
IClock clock = SystemClock.Instance; 
Instant now = clock.Now; 
LocalDate today = now.InZone(tz).Date; 

// combine the date and time 
LocalDateTime ldt = today.At(localTime); 

// bind it to the time zone 
ZonedDateTime result = ldt.InZoneLeniently(tz); 

Несколько замечаний:

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

  • Возможно, вы захотите установить это в функцию. Когда вы это сделаете, вы должны перейти в переменную clock в качестве параметра. Это позволит вам заменить системные часы для FakeClock в ваших модульных тестах.

  • Обязательно ознакомьтесь с тем, как InZoneLeniently ведет себя и замечает, как он меняется в предстоящей версии 2.0. См. «Изменения преобразователя Lenient» в the 2.x migration guide.

+0

Мне пришлось переключиться на 2.0.0 для функции .At для работы ... тогда мне пришлось использовать: Instant now = clock.GetCurrentInstant(); вместо clock.Now в 2.0.0. –

+0

'At' был добавлен в 1.3.0. Вы, должно быть, были на 1.2.0 раньше. В 1.2 вы должны использовать оператор '+' для объединения «LocalDate» и «LocalTime». (Вы все равно можете использовать это, если хотите.) Но да, метод для часов также изменился и в 2.0. –

+2

В 2.0 вы также можете использовать 'ZonedClock', чтобы сделать вещи проще, если вы собираетесь повторно использовать текущую дату/время из одного и того же часового пояса. –