Нам нужно довести время до ближайшего произвольного интервала (представленного, например, Timespan или Duration).
Предположим для примера, что нам нужно перекрыть его с точностью до десяти минут. например 13:02 становится 13:00, а 14:12 становится 14:10
Без использования Nodatime вы могли бы сделать что-то вроде вот этого:
// Floor
long ticks = date.Ticks / span.Ticks;
return new DateTime( ticks * span.Ticks );
Который будет использовать тики временного интервала, чтобы установить дату и время на определенное время.
Кажется, что NodaTime демонстрирует некоторую сложность, о которой мы раньше не думали. Вы можете написать такую функцию:
public static Instant FloorBy(this Instant time, Duration duration)
=> time.Minus(Duration.FromTicks(time.ToUnixTimeTicks() % duration.BclCompatibleTicks));
Но такая реализация кажется неправильной. «От минимума до ближайших десяти минут», похоже, зависит от часового пояса / смещения времени. Хотя это может быть 13:02 по всемирному координированному времени, в Непале со смещением +05: 45 время будет 18:47.
Это означает, что в всемирном координированном координированном времени, округление до ближайших десяти минут, означало бы вычитание двух минут, в то время как в Непале это означало бы вычитание семи минут.
Я чувствую, что должен каким-то образом обойти ZonedDateTime или OffsetDateTime на произвольный промежуток времени. Я могу приблизиться, написав такую функцию
public static OffsetDateTime FloorToNearestTenMinutes(this OffsetDateTime time)
{
return time
.Minus(Duration.FromMinutes(time.Minute % 10))
.Minus(Duration.FromSeconds(time.Second));
}
но это не позволяет мне указывать произвольную продолжительность, поскольку OffsetDateTime не имеет понятия тиков.
Как правильно округлить Instant / ZonedDateTime / OffsetDateTime с произвольным интервалом с учетом часовых поясов?