Я работаю над приложением, которое позволяет пользователю планировать событие. Пользователь указывает часовой пояс Olson с помощью средства выбора часового пояса, а также дату и время для указанное событие через сборщик календаря asp и сторонний сборщик времени ajax (поэтому поставляемый DateTime
всегда будет иметь один и тот же шаблон). Я сравниваю время, которое хочет пользователь, и часовой пояс, который пользователь предоставляет, со временем нашего сервера и его часовым поясом, и запускаю событие в тот момент, когда пользователь ожидает, что оно будет запущено.
Насколько я понимаю, прочитав эту ссылку в группе nodatime google, преобразование одного ZonedDateTime
в другой часовой пояс (используя WithZone
) довольно просто (как только я сопоставил событие пользователя с LocalDateTime
на ZonedDateTime
, очевидно). Мне не нужно беспокоиться о смещениях, и разница в летнем времени между, скажем, Фениксом и Чикаго будет правильно учтена.
Первоначально я преобразовал время сервера (DateTime.Now
) в ZonedDateTime
и сравнил таким образом, но после прочтения эта ссылка на SO Я переключился на использование IClock
.
Пока что в тестировании все работает, но меня беспокоят краеугольные случаи, которые я могу не тестировать. Согласно документации для NodaTime:
Самый большой «подводный камень» — это преобразование
LocalDateTime
вZonedDateTime
— у него есть несколько угловых случаев, которые вам нужно учитывать.
Я внимательно прочитал документацию и предполагаю, что эта ошибка относится к тем временам года, которые либо не наступают, либо наступают дважды. Это время никогда не будет установлено как время событий для наших пользователей, но я использую для них LenientResolver
. Есть ли какие-либо другие проблемы - когда я перехожу с LocalDateTime
на ZonedDateTime
, я ничего не упускаю или переход на летнее время в конечном итоге будет преследовать меня?
Кроме того, нужно ли перед сравнением преобразовывать ZonedDateTime
пользователя в часовой пояс сервера (что я и делаю сейчас) или это ненужный (или даже ошибочный) шаг? Сможет ли NodaTime правильно сравнивать (без проблем с переходом на летнее время), если я буду сравнивать непреобразованное ZonedDateTime
события (вместо ZonedDateTime
события после преобразования в часовой пояс сервера) с текущим сервером ZonedDateTime
(см. код ниже, третья до последней строки )? Просматривая код, я вижу время и смещения, но я беспокоюсь, что это может быть чрезмерным упрощением, которое приводит к проблемам.
Protected Function EventIsReady(ByVal insTimeZone As String, ByVal eventDate As DateTime) As Boolean
Dim clock As IClock = SystemClock.Instance
Dim now As Instant = clock.Now
'server time zone (America/Chicago), unfortunately not UTC
Dim zone = DateTimeZoneProviders.Tzdb("America/Chicago")
Dim serverZonedDateTime = now.InZone(zone)
'user time zone
Dim userTimeZone As NodaTime.DateTimeZone = NodaTime.DateTimeZoneProviders.Tzdb.GetZoneOrNull(insTimeZone)
Dim userEventLocalDateTime = LocalDateTime.FromDateTime(eventDate)
Dim eventZonedDateTime = userTimeZone.ResolveLocal(userEventLocalDateTime, Resolvers.LenientResolver)
Dim eventTimeInServerTimeZone = eventZonedDateTime.WithZone(zone)
Dim isReady As Boolean = False
If eventTimeInServerTimeZone >= serverZonedDateTime Then
isReady = True
End If
Return isReady
End Function