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

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
24-Май-2021 11:31

Микоропост о том, как можно себя обмануть при использовании фичи Котлин: возможность работы с операторами сравнения типа 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))
Вот так можно легко и непринужденно нарваться на неочевидную багу.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_java, #_kotlin, #_kotlin, #_java, #_java, #_kotlin
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 16-Ноя 17:53
Часовой пояс: UTC + 5