Урок 13

Новое Date/Time API


1. Старый Java API для работы с датами

java.util.Date и java.util.Calendar входят в старый Java API для работы с датами.

Недостатки:

  • не потокобезопасный, 
  • изменяемые классы,
  • временная зона даты – это временная зона JVM по умолчанию,
  • месяца начинаются с нуля.

2. Новый Date Time API

Новый  Java 8 Date/Time API содержит неизменные (immutable), потокобезопасные классы с продуманным дизайном. Содержатся они в пакете java.time.

Классы нового Date/Time API

  • LocalDate – представляет время с годом, месяцем и днем месяца. Например 2015-08-25.
  • LocalTime - представляет время с часами, минутами, секундами и наносекундами. Например 13:21.05.123456789.
  • LocalDateTime – комбинация содержимого LocalDate и LocalTime. Например 2015-08-25 13:21.05.12345.
  • Instant – представляет точку времени в секундах и наносекундах. Например 923,456,789 секунд и 186,054,812 наносекунд.
  • Period - представляет количество времени в годах, месяцах и днях. Например 5 лет, 2 месяца и 9 дней.
  • Duration - представляет количество времени в секундах и наносекундах. Например 12.87656 секунд.
LocalDate, LocalTime, LocalDateTime и Instant реализуют интерфейс java.time.temporal.Temporal. Period и Duration реализуют интерфейс java.time.temporal.TemporalAmount.

2.1. Класс LocalDate

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

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

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

LocalDate today = LocalDate.now();

Пример 1. Получение года, месяца, дня месяца

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);
    }
}

Пример 2. Получение года, месяца, дня месяца - второй вариант

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);
    }
}

Пример 3. Сравнение дат

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);
    }
}

Пример 4. Получение новой даты

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);
        System.out.println(newYear2004);
        System.out.println(december2001);
        System.out.println(february2001);
        System.out.println(xmas2001);
    }
}

Пример 5. Получение новой даты

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 january15_2001 = 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 dec30_2000 = newYear2001.minusDays(2);
        LocalDate lastWeekDec2001 = newYear2001.minusWeeks(1);
        LocalDate newYear1999 = newYear2001.minus(2, ChronoUnit.YEARS);
    }
}

2.2. Класс LocalTime

Пример 6. Создание объекта LocalTime

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);
    }
}

Пример 7. Создание объекта LocalTime

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);
    }
}

Пример 8. Создание объекта 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);
    }
}

Пример 9. Сравнение объектов LocalTime

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)); // false
        System.out.println(fiveThirty.isBefore(noon)); // true
        System.out.println(noon.equals(almostMidnight)); // false
    }
}

Пример 10. Создание объектов LocalTime

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);
    }
}

Пример 11. Создание объектов 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);
    }
}

2.3. Класс LocalDateTime

Пример 12. Создание объектов 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);
    }
}

Пример 13. Создание объектов 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);
    }
}

Пример 14. Создание объектов 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);
    }
}

Пример 15. Создание объектов LocalDateTime

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

public class LocalDateTimeDemo4 {
    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime newYear2001 = LocalDateTime.of(2001, 1, 1, 11, 23);
        // Adding
        LocalDateTime dt10 = now.plusYears(4);
        LocalDateTime dt11 = now.plusWeeks(3);
        LocalDateTime dt12 = newYear2001.plus(2, ChronoUnit.HOURS);

        // Subtracting
        LocalDateTime dt13 = now.minusMonths(2);
        LocalDateTime dt14 = now.minusNanos(1);
        LocalDateTime dt15 = now.minus(10, ChronoUnit.SECONDS);
    }
}

2.4. Класс Instant

Класс используется для представления мгновения в секундах, которые прошли с 1 января 1970 года.

Пример 16. Создание объектов Instant

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

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

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

        System.out.println(i1);
        System.out.println(now);
        System.out.println(fiveSecondsAfterEpoch);
        System.out.println(sixSecTwoNanBeforeEpoch);
        System.out.println(fifthyMilliSecondsAfterEpoch);
    }
}

Пример 17. Создание объектов 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 milis = 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("Милисекунды: " + milis);
        System.out.println("Наносекунды: " + nanos2);
    }
}

Пример 18. Сравнение объектов Instant

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));
        System.out.println(now.isBefore(fiveSecondsAfterEpoch));
        System.out.println(now.equals(fiveSecondsAfterEpoch));
    }
}

Пример 19. Сравнение объектов Instant

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

public class InstantDemo4 {
    public static void main(String[] args) {
        Instant now = Instant.now();
        // Добавление
        Instant dt10 = now.plusSeconds(400);
        Instant dt11 = now.plusMillis(98622200);
        Instant dt12 = now.plusNanos(300013890);
        Instant dt13 = now.plus(2, ChronoUnit.MINUTES);

        // Вычитание
        Instant dt14 = now.minusSeconds(2);
        Instant dt15 = now.minusMillis(1);
        Instant dt16 = now.minusNanos(1);
        Instant dt17 = now.minus(10, ChronoUnit.SECONDS);
    }
}

2.5. Класс Period

Класс представляет количество времени в годах, месяцах и днях.

Пример 20. Создание объектов 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);
    }
}

Пример 21. Создание объектов Period

Период можно рассматривать как разницу между двумя 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); // 2 месяца
        System.out.println(dif);
    }
}

Пример 22. Создание объектов Period

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

public class PeriodDemo3 {
    public static void main(String[] args) {
        Period dif1 = Period.between(LocalDate.of(2000, 2, 10),
                LocalDate.of(2001, 4, 12));
        Period dif2 = Period.between(LocalDate.of(2013, 5, 9),
                LocalDate.of(2013, 6, 3));
        Period dif3 = Period.between(LocalDate.of(2014, 11, 3),
                LocalDate.of(2012, 10, 31));
        System.out.println(dif1);
        System.out.println(dif2);
        System.out.println(dif3);
    }
}

Пример 23. Создание объектов 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);
    }
}

Пример 24. Создание объектов 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);
    }
}

Пример 25. Создание объектов 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));
    }
}

2.6. Класс Duration

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

Пример 26. Создание объектов Period

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

public class DurationDemo1 {
    public static void main(String[] args) {
        Duration oneDay = Duration.ofDays(1); // 1 day = 86400 seconds
        Duration oneHour = Duration.ofHours(1); // 1 hour = 3600 seconds
        Duration oneMin = Duration.ofMinutes(1); // 1 minute = 60 seconds
        Duration tenSeconds = Duration.ofSeconds(10);
        // Set seconds and nanoseconds (if they are outside the range
        // 0 to 999,999,999, the seconds will be altered, like below)
        Duration twoSeconds = Duration.ofSeconds(1, 1_000_000_000);
        // Seconds and nanoseconds are extracted from the passed millisecs
        Duration oneSecondFromMillis = Duration.ofMillis(2);
        // Seconds and nanoseconds are extracted from the passed nanos
        Duration oneSecondFromNanos = Duration.ofNanos(1000000000);
        Duration oneSecond = Duration.of(1, ChronoUnit.SECONDS);

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


0 comments
Leave your comment: