1. Дата и время (since version 8)

До Java 8 для работы с датой и временем использовались классы java.util.Date и java.util.Calendar. У них было много недостатков, например:

  • не потокобезопасный,

  • изменяемые объекты

  • временная зона даты – это временная зона JVM по умолчанию

  • месяца начинаются с нуля

В Java 8 добавили новую библиотеку, которая содержит неизменные (immutable), потокобезопасные (thread-safe) классы с более продуманным дизайном. Это классы LocalDate, LocalTime, LocalDateTime, Instant, Period и Duration. Содержатся они в пакете java.time и не содержат информацию о временной зоне (кроме класса Instant).

LocalDate, LocalTime, LocalDateTime и Instant реализуют интерфейс java.time.temporal.Temporal. Period и Duration реализуют интерфейс java.time.temporal.TemporalAmount.

Date and Time

2. Класс LocalDate

Класс LocalDate представляет время с годом, месяцем и днем месяца. Например 2015-08-25.

Для создания объекта класса используется метод of():

LocalDate newYear2001 = LocalDate.of(2001, 1, 1);
LocalDate newYear2002 = LocalDate.of(2002, Month.JANUARY, 1);

Для создания объекта, отображающего текущую дату, используется метод now():

LocalDate today = LocalDate.now();

Следующий пример показывает получение года, месяца, дня месяца:

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;

public class LocalDateDemo2 {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();

        int year = today.getYear();
        int month = today.getMonthValue();
        Month monthAsEnum = today.getMonth(); // как перечисление
        int dayYear = today.getDayOfYear();
        int dayMonth = today.getDayOfMonth();
        DayOfWeek dayWeekEnum = today.getDayOfWeek(); // как перечисление

        System.out.println("Год: " + year);
        System.out.println("Месяц: " + month);
        System.out.println("Название месяца: " + monthAsEnum);
        System.out.println("День в году: " + dayYear);
        System.out.println("День месяца: " + dayMonth);
        System.out.println("День недели: " + dayWeekEnum);
    }
}

Еще один вариант получение года, месяца, дня месяца:

import java.time.LocalDate;
import java.time.temporal.ChronoField;

public class LocalDateDemo3 {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();

        int year = today.get(ChronoField.YEAR);
        int month = today.get(ChronoField.MONTH_OF_YEAR);
        int dayYear = today.get(ChronoField.DAY_OF_YEAR);
        int dayMonth = today.get(ChronoField.DAY_OF_MONTH);
        int dayWeek = today.get(ChronoField.DAY_OF_WEEK);

        System.out.println("Год: " + year);
        System.out.println("Месяц: " + month);
        System.out.println("День в году: " + dayYear);
        System.out.println("День месяца: " + dayMonth);
        System.out.println("День недели: " + dayWeek);
    }
}

Для сравнения дат используются методы isAfter(), isBefore(), equals(), isLeapYear():

import java.time.LocalDate;
import java.time.Month;

public class CompareLocalDateDemo1 {
    public static void main(String[] args) {
        LocalDate newYear2001 = LocalDate.of(2001, 1, 1);
        LocalDate newYear2002 = LocalDate.of(2002, Month.JANUARY, 1);

        boolean after = newYear2001.isAfter(newYear2002);
        boolean before = newYear2001.isBefore(newYear2002);
        boolean equal = newYear2001.equals(newYear2002);
        boolean leapYear = newYear2001.isLeapYear();

        System.out.println("newYear2001.isAfter(newYear2002): " + after);
        System.out.println("newYear2001.isBefore(newYear2002): " + before);
        System.out.println("newYear2001.equals(newYear2002): " + equal);
        System.out.println("newYear2001.isLeapYear(): " + leapYear);
    }
}

Следующий пример показывает использование методов with() для изменения отдельно года, месяца, дня:

import java.time.LocalDate;
import java.time.temporal.ChronoField;

public class WithLocalDateDemo {
    public static void main(String[] args) {
        LocalDate newYear2001 = LocalDate.of(2001, 1, 1);

        LocalDate newYear2003 = newYear2001.with(ChronoField.YEAR, 2003);
        LocalDate newYear2004 = newYear2001.withYear(2004);
        LocalDate december2001 = newYear2001.withMonth(12);
        LocalDate february2001 = newYear2001.withDayOfYear(32);
        LocalDate xmas2001 = newYear2001.withMonth(12).withDayOfMonth(25);

        System.out.println("newYear2003 " + newYear2003);
        System.out.println("newYear2004 " + newYear2004);
        System.out.println("december2001 " + december2001);
        System.out.println("february2001 " + february2001);
        System.out.println("xmas2001 " + xmas2001);
    }
}

Методы plus(), minus() используются для добавления или вычитания года, месяца или дня:

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class PlusMinusLocalDateDemo {
    public static void main(String[] args) {
        LocalDate newYear2001 = LocalDate.of(2001, 1, 1);
        LocalDate newYear2005 = newYear2001.plusYears(4);
        LocalDate march2001 = newYear2001.plusMonths(2);
        LocalDate january15Year2001 = newYear2001.plusDays(14);
        LocalDate lastWeekJanuary2001 = newYear2001.plusWeeks(3);
        LocalDate newYear2006 = newYear2001.plus(5, ChronoUnit.YEARS);

        LocalDate newYear2000 = newYear2001.minusYears(1);
        LocalDate nov2000 = newYear2001.minusMonths(2);
        LocalDate dec30Year2000 = newYear2001.minusDays(2);
        LocalDate lastWeekDec2001 = newYear2001.minusWeeks(1);
        LocalDate newYear1999 = newYear2001.minus(2, ChronoUnit.YEARS);

        System.out.println("newYear2005: " + newYear2005);
        System.out.println("march2001: " + march2001);
        System.out.println("january15Year2001: " + january15Year2001);
        System.out.println("lastWeekJanuary2001: " + lastWeekJanuary2001);
        System.out.println("newYear2006: " + newYear2006);

        System.out.println("newYear2000: " + newYear2000);
        System.out.println("nov2000: " + nov2000);
        System.out.println("dec30Year2000: " + dec30Year2000);
        System.out.println("lastWeekDec2001: " + lastWeekDec2001);
        System.out.println("newYear1999: " + newYear1999);
    }
}

3. Класс LocalTime

Класс LocalTime представляет время с часами, минутами, секундами и наносекундами. Например 13:21.05.123456789.

Для создания объекта класса LocalTime используется метод of():

import java.time.LocalTime;

public class LocalTimeDemo1 {
    public static void main(String[] args) {
        // С часами (0-23) и минутами(0-59)
        LocalTime fiveThirty = LocalTime.of(5, 30);
        // С часами, минутами и секундами(0-59)
        LocalTime noon = LocalTime.of(12, 0, 0);
        // С часами, минутами, секундами и наносекундами(0-999,999,999)
        LocalTime almostMidnight = LocalTime.of(23, 59, 59, 999999);

        System.out.println(fiveThirty);
        System.out.println(noon);
        System.out.println(almostMidnight);
    }
}

Для получения объекта LocalTime, который содержит текущее время, используется метод now():

import java.time.LocalTime;

public class LocalTimeDemo2 {
    public static void main(String[] args) {
        LocalTime now = LocalTime.now();
        int hour = now.getHour();
        int minute = now.getMinute();
        int second = now.getSecond();
        int nanosecond = now.getNano();

        System.out.println("Часы: " + hour);
        System.out.println("Минуты: " + minute);
        System.out.println("Секунды: " + second);
        System.out.println("Наносекунды: " + nanosecond);
    }
}

Следующий пример показывает использование методов get() класса LocalTime для получения часов, минут или секунд:

import java.time.LocalTime;
import java.time.temporal.ChronoField;

public class LocalTimeDemo3 {
    public static void main(String[] args) {
        LocalTime now = LocalTime.now();
        int hourAMPM = now.get(ChronoField.HOUR_OF_AMPM); // 0 - 11
        int hourDay = now.get(ChronoField.HOUR_OF_DAY); // 0 - 23
        int minuteDay = now.get(ChronoField.MINUTE_OF_DAY); // 0 - 1,439
        int minuteHour = now.get(ChronoField.MINUTE_OF_HOUR); // 0 - 59
        int secondDay = now.get(ChronoField.SECOND_OF_DAY); // 0 - 86,399
        int secondMinute = now.get(ChronoField.SECOND_OF_MINUTE);// 0 - 59
        long nanoDay = now.getLong(ChronoField.NANO_OF_DAY);//0-86399999999
        int nanoSecond = now.get(ChronoField.NANO_OF_SECOND);//0-999999999

        System.out.println("Часы: " + hourAMPM);
        System.out.println("Часы: " + hourDay);
        System.out.println("Минуты дня: " + minuteDay);
        System.out.println("Минуты: " + minuteHour);
        System.out.println("Секунды дня: " + secondDay);
        System.out.println("Секунды: " + secondMinute);
        System.out.println("Наносекунды дня: " + nanoDay);
        System.out.println("Наносекунды: " + nanoSecond);
    }
}

Для сравнение объектов LocalTime используются методы isAfter(), isBefore() и equals():

import java.time.LocalTime;

public class CompareLocalTimeDemo {
    public static void main(String[] args) {
        LocalTime fiveThirty = LocalTime.of(5, 30);
        LocalTime noon = LocalTime.of(12, 0, 0);
        LocalTime almostMidnight = LocalTime.of(23, 59, 59, 999999);

        System.out.println("fiveThirty.isAfter(noon)? " + fiveThirty.isAfter(noon)); // false
        System.out.println("fiveThirty.isBefore(noon)? " + fiveThirty.isBefore(noon)); // true
        System.out.println("noon.equals(almostMidnight)? " + noon.equals(almostMidnight)); // false
    }
}

Для изменения часов, минут или секунд используются методы with():

import java.time.LocalTime;
import java.time.temporal.ChronoField;

public class WithLocalTimeDemo {
    public static void main(String[] args) {
        LocalTime noon = LocalTime.of(12, 0, 0);

        LocalTime ten = noon.with(ChronoField.HOUR_OF_DAY, 10);
        LocalTime eight = noon.withHour(8);
        LocalTime twelveThirty = noon.withMinute(30);
        LocalTime thirtyTwoSeconds = noon.withSecond(32);

        // Можно использовать сцепление методов
        LocalTime secondsNano = noon.withSecond(20).withNano(999999);

        System.out.println("ten: " + ten);
        System.out.println("eight: " + eight);
        System.out.println("twelveThirty: " + twelveThirty);
        System.out.println("thirtyTwoSeconds: " + thirtyTwoSeconds);
        System.out.println("secondsNano: " + secondsNano);
    }
}

Следующий пример показывает использование методов plus(), minus() класса LocalTime для добавления или удаления часов, минут или секунд:

import java.time.LocalTime;
import java.time.temporal.ChronoUnit;

public class PlusMinusLocalTimeDemo {
    public static void main(String[] args) {
        LocalTime fiveThirty = LocalTime.of(5, 30);
        // Добавление
        LocalTime sixThirty = fiveThirty.plusHours(1);
        LocalTime fiveForty = fiveThirty.plusMinutes(10);
        LocalTime plusSeconds = fiveThirty.plusSeconds(14);
        LocalTime plusNanos = fiveThirty.plusNanos(99999999);
        LocalTime sevenThirty = fiveThirty.plus(2, ChronoUnit.HOURS);

        // Вычитание
        LocalTime fourThirty = fiveThirty.minusHours(1);
        LocalTime fiveTen = fiveThirty.minusMinutes(20);
        LocalTime minusSeconds = fiveThirty.minusSeconds(2);
        LocalTime minusNanos = fiveThirty.minusNanos(1);
        LocalTime fiveTwenty = fiveThirty.minus(10, ChronoUnit.MINUTES);

        System.out.println("sixThirty: " + sixThirty);
        System.out.println("fiveForty: " + fiveForty);
        System.out.println("plusSeconds: " + plusSeconds);
        System.out.println("plusNanos: " + plusNanos);
        System.out.println("sevenThirty: " + sevenThirty);

        System.out.println("fourThirty: " + fourThirty);
        System.out.println("fiveTen: " + fiveTen);
        System.out.println("minusSeconds: " + minusSeconds);
        System.out.println("minusNanos: " + minusNanos);
        System.out.println("fiveTwenty: " + fiveTwenty);
    }
}

4. Класс LocalDateTime

Класс LocalDateTime используется для представления даты и времени. Это комбинация содержимого LocalDate и LocalTime. Например 2015-08-25 13:21.05.12345.

Рассмотрим пример создания объектов класса LocalDateTime:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class LocalDateTimeDemo1 {
    public static void main(String[] args) {
        // Секунды и наносекунды равны нулю
        LocalDateTime date1 = LocalDateTime.of(2014, 9, 19, 14, 5);
        // Наносекунды равны нулю
        LocalDateTime date2 = LocalDateTime.of(2014, 9, 19, 14, 5, 20);
        LocalDateTime date3 = LocalDateTime.of(2014, 9, 19, 14, 5, 20, 9);

        LocalDate date = LocalDate.now();
        LocalDateTime date4 = date.atTime(14, 30, 59, 999999);

        LocalTime time = LocalTime.now();
        LocalDateTime date5 = time.atDate(date);

        System.out.println(date1);
        System.out.println(date2);
        System.out.println(date3);
        System.out.println(date4);
        System.out.println(date5);
    }
}

Следующий пример показывает использование методов get() класса LocalDateTime:

import java.time.LocalDateTime;

public class LocalDateTimeDemo2 {
    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        int year = now.getYear();
        int dayYear = now.getDayOfYear();
        int hour = now.getHour();
        int minute = now.getMinute();

        System.out.println("Год: " + year);
        System.out.println("День в году: " + dayYear);
        System.out.println("Часы: " + hour);
        System.out.println("Минуты: " + minute);
    }
}

Рассмотрим пример использования методов with(), plus(), isAfter(), isBefore() класса LocalDateTime:

import java.time.LocalDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;

public class LocalDateTimeDemo3 {
    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();

        LocalDateTime date1 = now.with(ChronoField.HOUR_OF_DAY, 10);
        LocalDateTime date2 = now.withMonth(8);
        LocalDateTime date3 = now.withYear(2013).withMinute(0);

        // Сравнение
        boolean after = now.isAfter(date1);
        boolean before = now.isBefore(date1);
        boolean equal = now.equals(date1);

        // Добавление
        LocalDateTime date4 = now.plusYears(4);
        LocalDateTime date5 = now.plusWeeks(3);
        LocalDateTime date6 = date1.plus(2, ChronoUnit.HOURS);

        // Вычитание
        LocalDateTime date7 = now.minusMonths(2);
        LocalDateTime date8 = now.minusNanos(1);
        LocalDateTime date9 = now.minus(10, ChronoUnit.SECONDS);
    }
}

5. Класс Instant

Класс Instant используется для представления мгновения в секундах (Unix-время/Unix time/POSIX-время), которые прошли с 1 января 1970 года (этот момент называют эпохой Unix (Unix Epoch). Например: 923,456,789 секунд и 186,054,812 наносекунд.

Рассмотрим пример использования методов now(), ofEpochSecond(),` ofEpochMilli()` класса Instant:

import java.time.Instant;
import java.time.temporal.ChronoField;

public class InstantDemo1 {
    public static void main(String[] args) {
        Instant now = Instant.now();

        Instant instant = now.with(ChronoField.NANO_OF_SECOND, 10);
        // Устанавливаем секунды
        Instant fiveSecondsAfterEpoch = Instant.ofEpochSecond(5);
        // Устанавливаем секунды и наносекунды (могут быть отрицательные)
        Instant sixSecTwoNanBeforeEpoch = Instant.ofEpochSecond(-6, -2);
        // Устанавливаем милисекунды после (могут быть и до) эпохи
        Instant fiftyMilliSecondsAfterEpoch = Instant.ofEpochMilli(50);

        System.out.println("now: " + now);
        System.out.println("instant: " + instant);
        System.out.println("fiveSecondsAfterEpoch: " + fiveSecondsAfterEpoch);
        System.out.println("sixSecTwoNanBeforeEpoch: " + sixSecTwoNanBeforeEpoch);
        System.out.println("fiftyMilliSecondsAfterEpoch: " + fiftyMilliSecondsAfterEpoch);
    }
}

Следующий пример демонстрирует использование методов get() класса Instant для получения секунд, наносекунд и миллисекунд:

import java.time.Instant;
import java.time.temporal.ChronoField;

public class InstantDemo2 {
    public static void main(String[] args) {
        Instant now = Instant.now();
        long seconds = now.getEpochSecond(); // Получить секунды
        int nanos1 = now.getNano(); //Получить наносекунды
        // Получить значение как int
        int millis = now.get(ChronoField.MILLI_OF_SECOND);
        // Получить значение как long
        long nanos2 = now.getLong(ChronoField.NANO_OF_SECOND);

        System.out.println("Секунды: " + seconds);
        System.out.println("Наносекунды: " + nanos1);
        System.out.println("Милисекунды: " + millis);
        System.out.println("Наносекунды: " + nanos2);
    }
}

Объекты класса Instant можно сравнивать методами isAfter(), isBefore() и equals():

import java.time.Instant;

public class InstantDemo3 {
    public static void main(String[] args) {
        Instant now = Instant.now();
        Instant fiveSecondsAfterEpoch = Instant.ofEpochSecond(5);

        System.out.println("now.isAfter(fiveSecondsAfterEpoch)? " + now.isAfter(fiveSecondsAfterEpoch));
        System.out.println("now.isBefore(fiveSecondsAfterEpoch)? " + now.isBefore(fiveSecondsAfterEpoch));
        System.out.println("now.equals(fiveSecondsAfterEpoch)? " + now.equals(fiveSecondsAfterEpoch));
    }
}

Пример использования методов plus(), minus() класса Instant для добавления секунд, миллисекунд и наносекунд:

import java.time.Instant;
import java.time.temporal.ChronoUnit;

public class InstantDemo4 {
    public static void main(String[] args) {
        Instant now = Instant.ofEpochSecond(0);
        // Добавление
        Instant instant1 = now.plusSeconds(400);
        Instant instant2 = now.plusMillis(98622200);
        Instant instant3 = now.plusNanos(300013890);
        Instant instant4 = now.plus(2, ChronoUnit.MINUTES);

        // Вычитание
        Instant instant5 = now.minusSeconds(2);
        Instant instant6 = now.minusMillis(1);
        Instant instant7 = now.minusNanos(1);
        Instant instant8 = now.minus(10, ChronoUnit.SECONDS);

        System.out.println(now);
        System.out.println(instant1);
        System.out.println(instant2);
        System.out.println(instant3);
        System.out.println(instant4);

        System.out.println(instant5);
        System.out.println(instant6);
        System.out.println(instant7);
        System.out.println(instant8);
    }
}

6. Класс ZonedDateTime

Класс ZonedDateTime представляет дату и время с информацией о часовом поясе. Это может быть начало определенного события где-нибудь в мире, например конференции, запуска ракеты и т.д.

ZonedDateTimeКласс неизменяемый, это означает, что все методы, выполняющие вычисления над ZonedDateTime объектом, возвращают новый объект ZonedDateTime.

6.1. Создание ZonedDateTime объектов

Создать объект ZonedDateTime можно несколькими способами.

Первый способ - вызвать метод now() класса ZonedDateTime. Вот пример создания объекта ZonedDateTime`с помощью `now() метода:

ZonedDateTime zonedDateTime = ZonedDateTime.now();

Другой способ создать объект ZonedDateTime - использовать метод of(), который может создать ZonedDateTime объект на основе конкретной даты и времени. Вот пример создания объекта ZonedDateTime с помощью метода of():

ZoneId zoneId = ZoneId.of("UTC+1");

ZonedDateTime zonedDateTime2 =
    ZonedDateTime.of(2015, 11, 30, 23, 45, 59, 1234, zoneId);

6.2. Доступ к дате и времени ZonedDateTime

Можно получить доступ к полям даты и времени ZonedDateTime экземпляра, используя один из следующих методов:

  • getYear()

  • getMonth()

  • getDayOfMonth()

  • getDayOfWeek()

  • getDayOfYear()

  • getHour()

  • getMinute()

  • getSecond()

  • getNano()

Пример доступа к году ZonedDateTime:

int year = ZonedDateTime.now().getYear();

Некоторые из этих методов возвращают enum, а другие возвращают int. Из enums можно получить int представление их значения, используя метод getValue(). Например:

int month = ZonedDateTime.now().getMonth().getValue();

6.2.1. Расчет даты и времени

Класс ZonedDateTime содержит набор методов, используемых для расчета даты и времени. Вот некоторые из этих методов:

  • plusYears()

  • plusMonths()

  • plusDays()

  • plusHours()

  • plusMinutes

  • plusSeconds

  • plusNanos()

  • minusYears()

  • minusMonths()

  • minusDays()

  • minusHours()

  • minusMinutes

  • minusSeconds

  • minusNanos()

Имейте в виду, что расчеты, которые охватывают изменения летнего времени (начало или конец), могут не дать ожидаемого результата! Альтернативой является использование экземпляра класса Period, например:

ZonedDateTime newZoneDateTime = previousDateTime.plus(Period.ofDays(3));

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

6.3. Часовые пояса

Часовые пояса представлены классом ZoneId, как показано в предыдущем примере. Можно создать объект ZoneId с помощью метода now(). Вот пример:

ZoneId zoneId = ZoneId.of("UTC+1");

Параметр, передаваемый of() методу, - это идентификатор часового пояса, для которого создается ZoneId . В приведенном выше примере идентификатором является UTC+1, который является смещением от времени UTC (по Гринвичу). Можно найти смещение UTC для желаемого часового пояса и создать соответствующий ему идентификатор, объединив UTC со смещением (например, +1 или -5).

Вы также можете использовать другой тип идентификатора часового пояса, который состоит из названия места, где этот часовой пояс активен. Вот пример:

ZoneId zoneId2 = ZoneId.of("Europe/Copenhagen");
ZoneId zoneId3 = ZoneId.of("Europe/Paris");

7. Класс Period

Класс Period представляет количество времени в годах, месяцах и днях. Например: 5 лет, 2 месяца и 9 дней.

Рассмотрим пример создания объектов класса Period:

import java.time.Period;

public class PeriodDemo1 {
    public static void main(String[] args) {
        Period period5y4m3d = Period.of(5, 4, 3);
        Period period2d = Period.ofDays(2);
        Period period2m = Period.ofMonths(2);
        Period period14d = Period.ofWeeks(2);
        Period period2y = Period.ofYears(2);

        System.out.println(period5y4m3d);
        System.out.println(period2d);
        System.out.println(period2m);
        System.out.println(period14d);
        System.out.println(period2y);
    }
}

Период можно рассматривать как разницу между двумя LocalDate:

import java.time.LocalDate;
import java.time.Period;

public class PeriodDemo2 {
    public static void main(String[] args) {
        LocalDate march2003 = LocalDate.of(2003, 3, 1);
        LocalDate may2003 = LocalDate.of(2003, 5, 1);
        Period dif = Period.between(march2003, may2003);
        System.out.println(dif);
    }
}

Следующий пример показывает использование методов get() класса Period:

import java.time.Period;
import java.time.temporal.ChronoUnit;

public class PeriodDemo4 {
    public static void main(String[] args) {
        Period period5y4m3d = Period.of(5, 4, 3);
        int days = period5y4m3d.getDays();
        int months = period5y4m3d.getMonths();
        int year = period5y4m3d.getYears();
        long days2 = period5y4m3d.get(ChronoUnit.DAYS);

        System.out.println("Дни: " + days);
        System.out.println("Месяца: " + months);
        System.out.println("Годы: " + year);
        System.out.println("Дни: " + days2);
    }
}

Для изменения года, месяца или дня используются методы with() класса Period:

import java.time.Period;

public class PeriodDemo5 {
    public static void main(String[] args) {
        Period period2d = Period.ofDays(2);
        Period period8d = period2d.withDays(8);
        Period period2y1m2d = period2d.withYears(2).withMonths(1);

        System.out.println(period2d);
        System.out.println(period8d);
        System.out.println(period2y1m2d);
    }
}

Для добавления или удаления года, месяца или дня используются методы plus(), minus() класса Period:

import java.time.Period;

public class PeriodDemo6 {
    public static void main(String[] args) {
        Period period5y4m3d = Period.of(5, 4, 3);
        Period period2y = Period.ofYears(2);
        // Добавление
        System.out.println(period5y4m3d.plusYears(4));
        System.out.println(period5y4m3d.plusMonths(3));
        System.out.println(period5y4m3d.plusDays(3));
        System.out.println(period5y4m3d.plus(period2y));

        // Вычитание
        System.out.println(period5y4m3d.minusYears(2));
        System.out.println(period5y4m3d.minusMonths(1));
        System.out.println(period5y4m3d.minusDays(1));
        System.out.println(period5y4m3d.minus(period2y));
    }
}

8. Класс Duration

Класс Duration служит для хранения продолжительности времени на основе секунд и наносекунд. Например: 12.87656 секунд.

Также для отображения длительности можно использовать и другие величины, вроде минут, часов, дней. Однако, основное предназначение этого класса - представление небольших промежутков времени. Для работы с длительными промежутками времени предназначен другой класс - Period.

Рассмотрим пример создания объектов класса java.time.Duration:

import java.time.Duration;
import java.time.temporal.ChronoUnit;

public class DurationDemo1 {
    public static void main(String[] args) {
        Duration oneDay = Duration.ofDays(1);
        Duration oneHour = Duration.ofHours(1);
        Duration oneMin = Duration.ofMinutes(1);
        Duration tenSeconds = Duration.ofSeconds(10);
        Duration twoSeconds = Duration.ofSeconds(1, 1_000_000_000);
        Duration oneSecondFromMillis = Duration.ofMillis(1);
        Duration oneSecondFromNanos = Duration.ofNanos(1000000000);
        Duration oneSecond = Duration.of(1, ChronoUnit.SECONDS);

        System.out.println("oneDay: " + oneDay);
        System.out.println("oneHour: " + oneHour);
        System.out.println("oneMin: " + oneMin);
        System.out.println("tenSeconds: " + tenSeconds);
        System.out.println("twoSeconds: " + twoSeconds);
        System.out.println("oneSecondFromMillis: "+oneSecondFromMillis);
        System.out.println("oneSecondFromNanos: "+oneSecondFromNanos);
        System.out.println("oneSecond: "+oneSecond);
    }
}

9. Класс DateTimeFormatter

Класс DateTimeFormatter используется в Java 8 при форматировании и разборе даты.

Для создания объекта этого класса используется статический метод ofPattern(), на вход которого передается строка и объект класс Locale:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM, dd, yyyy HH:mm:ss", Locale.US);

Строка описывает формат написания даты и времени. Если локаль не указана, используется текущая локаль.

В следующей табличке указаны возможные символы, для описания формата даты:

Символ

Что означает

Пример

y

год в эре

2014; 14

M/L

месяц (название или номер)

9; 09; Sep; September; S

d

день месяца

17

E

день недели

Вт; вторник

h

время в 12-часовом формате

6

H

часы в 24-часовом формате

6

m

минуты

32

s

секунды

11

S

миллисекунды

109

Для разбора даты и времени из строковых значений существует два статических метода parse():

  • parse(CharSequence text) - конвертация строки, которая содержит дату и время, в объект LocalDateTime. При этом используется формат строки вида 2007-12-03T10:15:30.

  • parse(CharSequence text, DateTimeFormatter formatter) - конвертация строки, которая содержит дату и время, в объект LocalDateTime с использованием указанного формата.

Рассмотрим пример разбора даты:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class FormatLocalDateTimeDemo1 {
    public static void main(String[] args) {
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("MMMM d, yyyy HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.parse("июня 5, 2018 12:10:56", formatter1);
        System.out.println(localDateTime);

        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MMMM d, yyyy");
        LocalDate localDate = LocalDate.parse("июня 5, 2018", formatter2);
        System.out.println(localDate);
    }
}

Следующий пример описывает форматирование даты:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class FormatLocalDateTimeDemo2 {
    public static void main(String[] args) {
        LocalDateTime dateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM, dd, yyyy HH:mm:ss", Locale.US);
        System.out.println(dateTime.format(formatter));
    }
}