Java 8 New Date/Time API - Часть 6
Данная статья написана командой Vertex Academy. Это одна из статей из нашего Учебника по Java 8.
1. Введение
В предыдущей статье мы рассмотрели работу даты и времени с временными зонами в Java 8. В этой статье мы узнаем что такое Period и Duration, а так же поймем зачем оно нам нужно.
2. Period
Period указывает временной промежуток между двумя датами. Допустим, вам понадобилось узнать сколько осталось дней до дня рождения пользователя
1 2 3 4 5 6 7 8 9 |
LocalDate nextBirthday = LocalDate.of(2018, 9, 23); LocalDate now = LocalDate.now(); Period period = Period.between(now, nextBirthday); int days = period.getDays(); System.out.println(now); System.out.println(period); System.out.println(days); |
Можно предположить, что getDays() вернет количество дней до дня рождения. Так и будет, в буквальном смысле, ТОЛЬКО количество дней до дня рождения. Вывод в консоль ->
1 2 3 |
2018-02-11 P7M12D 12 |
Для того, чтобы вывести кол-во дней нормально, придется смотреть сколько дней в конкретном месяце, считать их самому и т.д.
Проще говоря, для такой задачи Period не очень подходит. Плюс ко всему с Period можно "переборщить"
1 2 3 4 5 |
Period period = Period.of(1, 15, 40); System.out.println(period); // P1Y15M40D int days = period.getDays(); System.out.println(days); // 40 |
Почему так??? Дело в том, что Period не имеет ограничений по количеству месяцев, дней. Но эту ситуацию можно немного исправить, для этого существует метод normalized()
1 2 3 4 5 |
Period period = Period.of(1, 15, 60).normalized(); System.out.println(period); // P2Y3M60D int days = period.getDays(); System.out.println(days); // 60 |
Количество дней никак не станет 30, 31, или 29. Ведь продолжительность не привязана к месяцам. Но если мы добавим Period к дате, все встанет на свои места.
1 2 3 |
Period period = Period.of(1, 15, 60); LocalDate localDate = LocalDate.of(2018, 1, 1); LocalDate plus = localDate.plus(period); // 2020-05-31 |
3. Duration
Duration, по сути, исполняет ту же роль, что и Period но измеряет все в часах, минутах, секундах ...
1 2 3 4 |
LocalTime _10AM = LocalTime.of(10, 10,15); LocalTime _9PM = LocalTime.of(21, 30); Duration duration = Duration.between(_10AM, _9PM); // PT11H19M45S |
Вот с помощью Duration можно решить нашу проблему с днём рождения, правда с маленькой хитростью.
1 2 3 4 5 |
LocalDate localDate = LocalDate.of(2018, 2, 11); LocalDate birthday = LocalDate.of(2018, 9, 23); Duration duration = Duration.between(localDate.atStartOfDay(), birthday.atStartOfDay()); System.out.println(duration.toDays()); // 224 |
Duration не работает с LocalDate, зато с LocalDateTime еще как. Преобразовав одно в другое с помощью метода atStartOfDay(), мы можем получить Duration, а уже у него получить количество дней.
Конечно, можно пойти путем еще проще, используя класс ChronoUnit
1 2 3 4 |
LocalDate localDate = LocalDate.of(2018, 2, 11); LocalDate birthday = LocalDate.of(2018, 9, 23); long daysToBirthday = ChronoUnit.DAYS.between(localDate, birthday); // 224 |
Что еще раз доказывает - существует множество вариантов решения одной и той же задачи, не все из них хороши, не все так изящны, но чем больше вариантов вы знаете, тем больше возможностей у вас есть. Поэтому развивайтесь, узнавайте новое и Never Give Up
А в следующей статье мы рассмотрим TemporalAdjuster. Спасибо, что были с нами 🙂