java.time
Новая инфраструктура java.time, встроенная в Java 8 и более поздние версии, заменяет старые запутанные классы java.util.Date/.Calendar
В учебнике показано, как получить промежуток времени, определяемый как общее количество дней, а также период, логическое число лет, месяцев и дней.
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);
Period p = Period.between(birthday, today);
long p2 = ChronoUnit.DAYS.between(birthday, today);
System.out.println("You are " + p.getYears() + " years, " + p.getMonths() +
" months, and " + p.getDays() +
" days old. (" + p2 + " days total)");
Код производит вывод, подобный следующему:
Вам 53 года, 4 месяца и 29 дней. (Всего 19508 дней)
Я бы улучшил пример Tutorial, передав часовой пояс в now
, а не полагаясь косвенно на текущий часовой пояс JVM по умолчанию, который может измениться в любой момент. В то время как LocalDate не имеет назначенного часового пояса (это то, что означает локальный), при определении даты часовой пояс имеет решающее значение. Например, в Париже новый день наступает раньше, чем в Монреале.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
Чтобы получить дни до следующего дня рождения, создайте будущую дату, подставив год. Инфраструктура Java.time использует неизменяемые объекты, поэтому этот показанный синтаксис создает новый объект на основе значений оригинала, оставляя оригинал нетронутым и незатронутым.
LocalDate birthdayThisYear = birthday.withYear( today.getYear() );
if ( birthdayThisYear.isBefore( today ) ) {
birthdayThisYear.plusYears( 1 );
}
long daysUntilBirthday = ChronoUnit.DAYS.between( today , birthdayThisYear );
Joda-Time
Библиотека Joda-Time послужила источником вдохновения для java.time. Используйте Joda-Time, когда технология Java 8 недоступна, например, в Android. Специально для Android вы можете найти специальные сборки Joda-Time из других источников, чтобы решить проблему медленной загрузки в Dalvik.
В этом случае код похож между Joda-Time и java.time.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
LocalDate today = LocalDate.now( zone );
LocalDate birthdate = new LocalDate( 1966 , 1 , 2 );
LocalDate nextBirthday = birthdate.withYear( today.getYear() );
if ( nextBirthday.isBefore( today ) ) {
nextBirthday = nextBirthday.plusYears( 1 );
}
int daysUntilBirthday = Days.daysBetween( today , nextBirthday ).getDays();
Joda-Time также предлагает класс Period. Однако этот класс обрабатывает неполные дни, тогда как java.time Period - только целые дни. Поэтому нам нужно преобразовать наши экземпляры LocalDate в экземпляры DateTime для подачи в конструктор Period.
DateTime start = today.toDateTimeAtStartOfDay( zone );
DateTime stop = nextBirthday.toDateTimeAtStartOfDay( zone );
Period period = new Period( start , stop );
Форматтер по умолчанию использует стандартные форматы ISO 8601. Таким образом, вызов period.toString()
отображает что-то вроде этого на три месяца и два дня:
P3M2D