Статьи

Что нового в Java 8 — API даты, часть II

Этот пост является продолжением нашего обзора   API даты, который вышел с выпуском Java 8. Мы собираемся продолжить нашу концентрацию на классах, которые упрощают работу с датами / временем. Работа с объектами даты в предыдущих выпусках Java была очень сложной в плане добавления времени или получения разницы между датами. Надеемся, что после просмотра классов, представленных здесь, ваше мнение о работе с датами и временем в Java изменится. В частности, мы рассмотрим следующие классы:

  • Другие классы для представления даты / времени  ZonedDateTime и OffsetDateTime
  • Получение текущего снимка во времени с Instant
  • Использование  Clock класса, чтобы получить системное время, но указать разные часовые пояса
  • Представлять произвольное количество дней с  Period классом
  • Представлять произвольное количество часов с  Duration классом

Зонированные / смещенные даты и время

В  последнем посте  мы рассмотрели  LocalDateTimeLocalDate и  LocalTime классы. Как следует из названия, эти классы дают дату и / или время для данного населенного пункта без часового пояса или смещения от времени UTC / Greenwhich. Java 8 предоставляет   класс ZonedDateTime, который предоставляет дату и время представлением часового пояса. Создание  ZonedDateTime экземпляра может быть выполнено несколькими способами, но здесь мы продемонстрируем использование двух из множества статических фабричных методов:


Создание экземпляра ZonedDateTime
 //Uses the system clock using the default time-zone.
 ZonedDateTime zdt = ZonedDateTime.now();
 //Displays as 2014-03-28T21:52:09.122-04:00
 //Uses the system clock with the specified time-zone
 ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/Dublin"));
 //Displays as 2014-03-29T01:45:34.605Z[Europe/Dublin]

Далее у нас есть  OffsetDateTime и те  OffsetTime классы , которые представляют собой дату и время , или время (соответственно) с смещениями от UTC / Greenwhich времени. Здесь мы показываем создание  OffsetDateTimeи  OffsetTime использование некоторых других доступных статических фабричных методов:


Создание экземпляров OffsetDateTime / OffsetTime

OffsetDateTime odt = OffsetDateTime.of(LocaDateTime.now(),ZoneOffset.of("-4"));
//Displays as 2014-03-28T22:30:28.911-04:00
OffsetTime ot = OffsetTime.ofInstant(Intant.now(),ZoneId.of("America/Los_Angeles"));
//Displays as 19:45:40.661-07:00

В последнем примере мы видим использование  Instant класса, который мы скоро представим. Стоит отметить , в этот момент , что  ZondedDateTime, OffsetDateTime классы хранят время до наносекундной точности. Обычно мы используем  ZonedDateTime класс при отображении даты и времени пользователям и  OffsetDateTime класс при взаимодействии с системами.

Часы

[A href = «http://docs.oracle.com/javase/8/docs/api/java/time/Clock.html» style = «font-style: наследовать; вариант шрифта: наследовать; вес шрифта : наследовать; высота строки: наследовать; размер шрифта: 18 пикселей; цвет: rgb (117, 21, 144); -вебкит-переход: цвет 0,3 с; переход: цвет 0,3 с; пробел: предварительная переноска; слово -wrap: break-word; «] Класс часов дает нам возможность получить текущую дату / время из системных часов с определенным часовым поясом. Хотя существуют классы даты и времени, у которых есть  now() метод, возвращающий текущую дату и время, системные часы используют часовой пояс по умолчанию. Clock Класс позволяет получить системное время с заданной временной зоной. Затем мы можем подключить  Clock экземпляр к другим классам, где мы хотим получить текущее время, используя данный часовой пояс.


Создание экземпляров часов
//Returns Clock with default time-zone
Clock default = Clock.systemDefaultZone();
//Clock with desired time-zone
Clock clock = Clock.system(ZoneId.of("America/Chicago"));

Теперь мы можем переработать наш предыдущий пример создания  OffsetTime объекта, используя  Clockэкземпляр для установки желаемого часового пояса:


Использование часов с OffsetDateTime
Clock clock = Clock.system(ZoneId.of("America/Los_Angeles"));
......
public void someOperation(Clock clock){
     OffsetTime ot = OffsetTime.of(clock);
     ... some work involving the OffsetTime intance
}

Clock Класс также позволяет указать , как она «галочка», это означает , что мы можем иметь время вернулись из  Clock экземпляра тикает на целых минутах или секундах


Установка уровня «тик» для часов
Clock wholeMinuteClock = Clock.tickMinutes(ZoneId.of("Europe/Athens"));
Clock wholeSecondClock = Clock.tickSeconds(ZonieId.of("Europe/Prauge"));

Мгновенное

Класс  Instant  используется для захвата текущего «момента» во времени. Instant Класс полезен для получения временных меток событий , а также имеет точность наносекунд.


Получение Мгновенного
//Record the current moment on the time-line from the system clock
Instant now = Instant.now();
//Record the current instant with the given Clock instance
Instance now = Instant.now(clock)

В  Instant классе есть несколько других методов для настройки  Instant экземпляра, таких как добавление / вычитание времени или преобразование в  OffsetDateTime или  ZonedDateTime.

период

Класс  Period  представляет произвольное количество времени в годах, месяцах или днях. Period объекты могут быть особенно полезны для добавления / вычитания времени из даты. Например:


Использование класса Period для добавления или вычитания дат
@Test
public void test_add_days(){
    LocalDateTime today = LocalDateTime.parse("2014-03-12T19:36:33");
    Period sixDays = Period.ofDays(6);
    LocalDateTime nextWeek = today.plus(sixDays);
    assertThat(nextWeek.toString(),is("2014-03-18T19:36:33"));
}
@Test
public void test_subtract_days(){
    LocalDate today = LocalDate.parse("2014-03-12");
    Period twoWeeks = Period.ofWeeks(2);
    LocalDate past = today.minus(twoWeeks);
    assertThat(past.toString(),is("2014-02-26"));
}

Period Класс также предлагает статический метод  , Period.between который является большим для определения истекшего времени между датами:


Получение времени между датами с классом Period
@Test
public void test_period_between_dates(){
    LocalDate twins = LocalDate.parse("2003-11-18");
    LocalDate mayhem = LocalDate.parse("2009-06-01");
    Period timeBetween = Period.between(twins,mayhem);
    assertThat(timeBetween.getYears(),is(5));
    assertThat(timeBetween.getMonths(),is(6));
    assertThat(timeBetween.getDays(),is(14));
}

Хотя для  Period.between метода требуются типы  LocalDate, классы даты и времени в  java.time пакете предлагают  toLocalDate() метод, который возвращает значение  LocalDate из экземпляра даты и времени.

продолжительность

Класс  Duration  представляет произвольное количество времени в часах, минутах или секундах. Шаблон использования для  Duration аналогичен тому из  Period класса. Вот примеры настройки временных объектов с помощью  Duration класса:


используя Duration для добавления / вычитания времени
@Test
public void test_add_time(){
    Duration oneHourThirtyMinutes = Duration.ofHours(1).plusMinutes(30);
    OffsetTime now = OffsetTime.parse("10:15:30-05:00");
    OffsetTime later = now.plus(oneHourThirtyMinutes);
    assertThat(later.toString(),is("11:45:30-05:00"));
    Duration threeHours = Duration.parse("PT3H");
    LocalTime twoPM = LocalTime.parse("14:00:00");
    LocalTime fivePM = twoPM.plus(threeHours);
    assertThat(fivePM.toString(),is("17:00"));
}
@Test
public void test_subtract_time(){
    OffsetTime offsetTime = OffsetTime.parse("13:34:00+01:00");
    LocalTime earlier = LocalTime.parse("09:30:25");
    LocalTime later = LocalTime.parse("15:33:47");
    Duration timeSpan = Duration.between(earlier,later);
    OffsetTime adjustedOffsetTime = offsetTime.minus(timeSpan);
    assertThat(adjustedOffsetTime.toString(),is("07:30:38+01:00"));
}

В  Duration классе также есть  between метод определения количества времени (в часах) между объектами времени:


используя Duration для определения разницы между объектами времени
@Test
public void test_time_between(){
    LocalTime earlier = LocalTime.parse("09:30:25");
    LocalTime later = LocalTime.parse("15:33:47");
    Duration timeSpan = Duration.between(earlier,later);
    assertThat(timeSpan.toString(),is("PT6H3M22S"));
    assertThat(LocalTime.MIDNIGHT.plus(timeSpan).toString(),is("06:03:22"));
}

Duration.between Метод требует типов  Temporal. Все классы времени и даты в  java.time пакете реализуют  Temporal интерфейс.

Вывод

Это завершает наш краткий обзор нового API даты в Java 8. Надеюсь, вы сможете увидеть обещание в новом API даты для работы с датами и временем. В следующих статьях я планирую продолжить рассказ о новых возможностях Java 8. Спасибо за ваше время.

Ресурсы