Работа с java.time в Kotlin: любовь, боль, страдания

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Микоропост о том, как можно себя обмануть при использовании фичи Котлин: возможность работы с операторами сравнения типа Comparable.

Кто юзает Котлин не могли не оценить перегрузку операторов (ну точнее как она сделана), правда я допустим жил в Java и без нее прекрасно, но да тут не об этой фичи языка, а об основанной на ней: Comparison Operations. Это когда можно применять знаки сравнения для классов, реализующих Comparable, что является сахаром, но очень приятным.

И так, поупражняемся на синтетике: у нас есть какой-либо временной отрезок, т.е. начальная и конечная дата время и нам нужно проверить факт пересечения временных отрезков.

На Java (пишу максимально кратко и без принятых норм, просто передать идею):

class TimeIterval {
  LocalDateTime from;
  LocalDateTime to;
}
class TimeIntervalUtil {
  public boolean areOverlapped(TimeInterval first, TimeInterval second) {
            return (first.from.isEqual(second.to) || first.from.isBefore(second.to)) &&
                (first.to.isEqual(second.from) || first.to.isAfter(second.from));
  }
}

т.е. ничего сложного, но на всякий случай поясню код (мне приходиться самому пояснять себе такой код, когда его встречаю): пересечение двух интервалов возможно только если дата начала одного наступила ранее или в тот же момент времени по отношению к дате окончания второго и в это же время дата окончания первого интервала наступает позднее или в момент начала второго.

Теперь то же самое но на Котлине с его сахаром, но без рейнджей:

data class TimeInterval(val from: LocalDateTime, val to: LocalDateTime)
fun areOverlapped(first: TimeInterval, second: TimeInterval): Boolean = 
  first.from <= second.to && first.to >= second.from

Ну я думаю без комментариев где видно лучше, что приятней использовать и быстрее понимать. Довольные переходим на Котлин и начинаем работать по аналогии уже с OffsetDateTime.

Тут нам нужно сделать то же самое, но уже с OffsetDateTime. Он тоже Comparable, как и почти все в java.time. Следовательно мы будем использовать такие же подходы как и LocalDateTime. В частности на Java код точно не измениться и будет работать так же как и ранее, а вот с Котлином будет засада.

Если посмотреть compareTo, в вызовы которого интерпретируется код на Kotlin при использовании знаков сравнения, то окажется что для LocalDateTime в принципе получается корректный код (сравниваются дни, часы, месяца и прочее по отдельности), что вроде как нормально.

В случае с OffsetDateTime будет сравнение, не которое мы ожидаем получить, так как compareTo учитывает зону времени, т.е. при сравнении 2021-04-25 10:00+0 и 2021-04-25 11:00+1 они не будут эквиваленты. Простой пример:

val inUtc = OffsetDateTime.of(LocalDateTime.of(2021, 4, 25, 10, 0), ZoneOffset.UTC)
val inUtc1 = OffsetDateTime.of(LocalDateTime.of(2021, 4, 25, 11, 0), ZoneOffset.ofTotalSeconds(60*60))
println(inUtc1>=inUtc && inUtc1 <= inUtc)
println(inUtc.isEqual(inUtc1))

Вот так можно легко и непринужденно нарваться на неочевидную багу.

Источник: https://habr.com/ru/post/558896/


Интересные статьи

Интересные статьи

Ранее в одном из наших КП добавление задач обрабатывалось бизнес-процессами, сейчас задач стало столько, что бизнес-процессы стали неуместны, и понадобился инструмент для массовой заливки задач на КП.
Этот пассажир не так чихнул в полёте. На самом деле учения, фото из архива аэропорта KZN. 2016 год, борт Пхукет-Москва запросил вынужденную посадку. На борту женщина собирается рожать. КВС р...
Возможно, прозрачность не кажется какой-то интересной темой. Формат GIF, позволявший некоторым пикселям просвечивать сквозь фон, опубликован более 30 лет назад. Почти в каждом приложении для гр...
Вчера Amazon впервые представила собственный дрон для доставки – на своей первой конференции Re:Mars в Лас-Вегасе. Это на самом деле уникальное устройство, доверху напичканное сенсорами и алг...
Согласно многочисленным исследованиям поведения пользователей на сайте, порядка 25% посетителей покидают ресурс, если страница грузится более 4 секунд.