«1. Обзор

В этом руководстве мы рассмотрим класс Java Clock из пакета java.time. Мы объясним, что такое класс Clock и как мы можем его использовать.

2. Класс Clock

Часы были добавлены в Java 8 и обеспечивают доступ к моменту времени с использованием наилучших доступных системных часов, а также для использования в качестве поставщика времени, который можно эффективно заглушить для целей тестирования.

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

Этот класс помогает нам проверить, что изменения в нашем коде работают с разными часовыми поясами или — при использовании фиксированных часов — что время не влияет на наш код.

Класс Clock является абстрактным, поэтому мы не можем создать его экземпляр. Можно использовать следующие фабричные методы:

    offset(Clock, Duration) — возвращает часы со смещением на указанную длительность. Основной вариант использования для этого — имитация работы в будущем или прошлом. Наиболее часто это используется в тестировании, где фиксированные часы гарантируют, что тесты не зависят от текущих часов

Мы рассмотрим большинство методов, доступных в классе Clock.

2.1. Instant()

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

Clock clock = Clock.systemDefaultZone();
Instant instant = clock.instant();
System.out.println(instant);

выдаст:

2018-04-07T03:59:35.555Z

2.2. systemUTC()

Этот метод возвращает объект Clock, представляющий текущий момент в зоне UTC:

Clock clock = Clock.systemUTC();
System.out.println("UTC time :: " + clock.instant());

выдаст:

UTC time :: 2018-04-04T17:40:12.353Z

2.3. system()

Этот статический метод возвращает объект Clock для часового пояса, определенного заданным идентификатором часового пояса:

Clock clock = Clock.system(ZoneId.of("Asia/Calcutta"));
System.out.println(clock.instant());

выдаст:

2018-04-04T18:00:31.376Z

2.4. systemDefaultZone()

Этот статический метод возвращает объект Clock, представляющий текущий момент и использующий часовой пояс по умолчанию системы, в которой он работает:

Clock clock = Clock.systemDefaultZone();
System.out.println(clock);

Приведенные выше строки дают следующий результат (при условии, что наш часовой пояс по умолчанию равен «Азия/Калькутта» ):

SystemClock[Asia/Calcutta]

Мы можем добиться такого же поведения, передав ZoneId.systemDefault():

Clock clock = Clock.system(ZoneId.systemDefault());

2.5. millis()

Этот метод возвращает текущий момент времени в миллисекундах. Это позволяет использовать часы в высокопроизводительных случаях, когда создание объекта было бы неприемлемо. Этот метод можно использовать там, где в противном случае мы использовали бы System.currentTimeInMillis():

Clock clock = Clock.systemDefaultZone();
System.out.println(clock.millis());

выдаст:

1523104441258

2.6. offset()

Этот статический метод возвращает момент из указанных базовых часов с добавлением указанной длительности.

Если продолжительность отрицательна, то результирующий момент времени будет раньше, чем заданное базовое время.

Используя смещение, мы можем получить моменты в прошлом и будущем заданных базовых часов. Если мы укажем нулевую длительность, то получим те же часы, что и заданные базовые часы:

Clock baseClock = Clock.systemDefaultZone();

// result clock will be later than baseClock
Clock clock = Clock.offset(baseClock, Duration.ofHours(72));
System.out.println(clock5.instant());

// result clock will be same as baseClock                           
clock = Clock.offset(baseClock, Duration.ZERO);
System.out.println(clock.instant());

// result clock will be earlier than baseClock            
clock = Clock.offset(baseClock, Duration.ofHours(-72));
System.out.println(clock.instant());

будет производить:

2018-04-10T13:24:07.347Z
2018-04-07T13:24:07.348Z
2018-04-04T13:24:07.348Z

2.7. tick()

Этот статический метод возвращает мгновения от указанных часов, округленные до ближайшего появления указанной продолжительности. Заданная продолжительность такта должна быть положительной:

Clock clockDefaultZone = Clock.systemDefaultZone();
Clock clocktick = Clock.tick(clockDefaultZone, Duration.ofSeconds(30));

System.out.println("Clock Default Zone: " + clockDefaultZone.instant());
System.out.println("Clock tick: " + clocktick.instant());

выдаст:

Clock Default Zone: 2018-04-07T16:42:05.473Z
Clock tick: 2018-04-07T16:42:00Z

2.8. tickSeconds()

Этот статический метод возвращает текущий момент времени в целых секундах для заданного часового пояса. В этих часах поле наносекунд всегда будет установлено на ноль:

ZoneId zoneId = ZoneId.of("Asia/Calcutta");
Clock clock = Clock.tickSeconds(zoneId);
System.out.println(clock.instant());

выдаст:

2018-04-07T17:40:23Z

То же самое можно сделать, используя tick():

Clock clock = Clock.tick(Clock.system(ZoneId.of("Asia/Calcutta")), Duration.ofSeconds(1));

2.9. tickMinutes()

Этот статический метод возвращает тиканье часов в целых минутах для указанного часового пояса. Эти часы всегда будут иметь поля наносекунд и секунд минут, установленные на ноль:

ZoneId zoneId = ZoneId.of("Asia/Calcutta");
Clock clock = Clock.tickMinutes(zoneId);
System.out.println(clock.instant());

выдаст:

2018-04-07T17:26:00Z

То же самое можно сделать, используя tick(): ~

Clock clock = Clock.tick(Clock.system(ZoneId.of("Asia/Calcutta")), Duration.ofMinutes(1));

2.10. withZone()

Этот метод возвращает копию этих часов с другим часовым поясом.

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

ZoneId zoneSingapore = ZoneId.of("Asia/Singapore");  
Clock clockSingapore = Clock.system(zoneSingapore); 
System.out.println(clockSingapore.instant());

ZoneId zoneCalcutta = ZoneId.of("Asia/Calcutta");
Clock clockCalcutta = clockSingapore.withZone(zoneCalcutta);
System.out.println(clockCalcutta.instant());

выдаст:

2018-04-07T17:55:43.035Z
2018-04-07T17:55:43.035Z

2.11. получитьзону()

«Этот метод возвращает часовой пояс заданных часов.

Clock clock = Clock.systemDefaultZone();
ZoneId zone = clock.getZone();
System.out.println(zone.getId());

выдаст:

Asia/Calcutta

2.12. fixed()

Этот метод возвращает часы, которые всегда возвращают один и тот же момент времени. Основной вариант использования этого метода — тестирование, где фиксированные часы гарантируют, что тесты не зависят от текущих часов.

Clock fixedClock = Clock.fixed(Instant.parse("2018-04-29T10:15:30.00Z"),
ZoneId.of("Asia/Calcutta"));
System.out.println(fixedClock);

выдаст:

FixedClock[2018-04-29T10:15:30Z,Asia/Calcutta]

3. Заключение

В этой статье мы углубились в класс Java Clock и различные способы его использования с доступными методами.

Как всегда, примеры кода доступны на GitHub.