Класс Java Duration
Класс Duration — важный класс в API даты и времени (пакете java.time), представленном в Java 8, используемый для представления временных интервалов или длительностей.
Класс Duration в основном используется для вычисления разницы между двумя моментами времени или для представления определённой длины времени.
Базовые понятия
Временной интервал, представленный классом Duration, может быть точен до наносекунд. Он в основном используется для работы с величинами времени (часы, минуты, секунды и наносекунды), не затрагивая понятия даты или часовых поясов.
Основные возможности:
- Неизменяемость — после создания объекта Duration его нельзя изменить
- Потокобезопасность — можно безопасно использовать в многопоточных средах
- Высокая точность — может быть точен до наносекунд
- Цепочки вызовов — поддерживает цепочки методов
Создание объектов Duration
Класс Duration предоставляет несколько статических методов для создания экземпляров Duration:
1. Создание через единицы времени
Пример
Duration twoHours = Duration.ofHours(2);
// Создать Duration продолжительностью 30 минут
Duration thirtyMinutes = Duration.ofMinutes(30);
// Создать Duration продолжительностью 45 секунд
Duration fortyFiveSeconds = Duration.ofSeconds(45);
// Создать Duration продолжительностью 500 миллисекунд
Duration fiveHundredMillis = Duration.ofMillis(500);
// Создать Duration продолжительностью 1,000,000 наносекунд
Duration oneMillionNanos = Duration.ofNanos(1_000_000);
2. Создание через Time Amount
Пример
Duration customDuration = Duration.ofDays(1).plusHours(2).plusMinutes(3);
3. Вычисление с помощью двух моментов времени
Пример
// Выполнить некоторые операции...
Instant end = Instant.now();
Duration elapsed = Duration.between(start, end);
4. Создание путём разбора строки
Пример
Duration parsedDuration = Duration.parse("PT2H30M15S"); // 2 часа, 30 минут, 15 секунд
Общие методы
Класс Duration предоставляет разнообразные методы для работы с временными интервалами:
1. Получение значений времени
Пример
long hours = duration.toHours(); // 2
long minutes = duration.toMinutes(); // 150
long seconds = duration.getSeconds(); // 9000
int nanos = duration.getNano(); // 0
2. Операции со временем
Пример
Duration d2 = Duration.ofMinutes(30);
// Сложение
Duration sum = d1.plus(d2); // 2 часа 30 минут
// Вычитание
Duration diff = d1.minus(d2); // 1 час 30 минут
// Умножение
Duration multiplied = d1.multipliedBy(3); // 6 hours
// Деление
Duration divided = d1.dividedBy(2); // 1 hour
3. Операции сравнения
Пример
Duration d2 = Duration.ofMinutes(90);
boolean isEqual = d1.equals(d2); // false
int comparison = d1.compareTo(d2); // -1 (d1 < d2)
boolean isNegative = d1.isNegative(); // false
boolean isZero = d1.isZero(); // false
4. Другие практические методы
Пример
// Преобразовать в другие единицы
long hours = duration.toHours(); // 1
long minutes = duration.toMinutes(); // 90
long seconds = duration.toSeconds(); // 5400
long millis = duration.toMillis(); // 5400000
long nanos = duration.toNanos(); // 5400000000000
// Получить каждую часть
long secondsPart = duration.getSeconds(); // 5400
int nanoPart = duration.getNano(); // 0
// Получить абсолютное значение
Duration absDuration = duration.abs();
// Получить отрицательное значение
Duration negated = duration.negated();
Примеры практического применения
Пример 1: Вычисление времени выполнения кода
Пример
// Имитация длительной операции
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Instant end = Instant.now();
Duration elapsed = Duration.between(start, end);
System.out.println("Время выполнения кода: " + elapsed.toMillis() + " миллисекунд");
Пример 2: Преобразование формата времени
Пример
// Преобразовать в формат "HH:MM:SS"
long hours = duration.toHours();
long minutes = duration.minusHours(hours).toMinutes();
long seconds = duration.minusHours(hours).minusMinutes(minutes).getSeconds();
String formatted = String.format("%02d:%02d:%02d", hours, minutes, seconds);
System.out.println(formatted); // Вывод: 02:15:00
Пример 3: Управление тайм-аутом
Пример
Instant startTime = Instant.now();
while (true) {
// Проверить, истек ли тайм-аут
if (Duration.between(startTime, Instant.now()).compareTo(timeout) > 0) {
System.out.println("Истекло время ожидания");
break;
}
// Выполнить другие операции...
}
Пример
import java.time.LocalTime;
import java.time.Instant;
public class DurationDemo {
public static void main(String[] args) {
// Несколько способов создания объектов Duration
// 1. Использование метода of...()
Duration duration1 = Duration.ofHours(2); // 2 часа
Duration duration2 = Duration.ofMinutes(90); // 90 минут
System.out.println("Длительность 1: " + duration1);
System.out.println("Длительность 2: " + duration2);
// 2. Используйте метод between() для вычисления длительности между двумя моментами времени
LocalTime startTime = LocalTime.of(9, 0);
LocalTime endTime = LocalTime.of(11, 30);
Duration duration3 = Duration.between(startTime, endTime);
System.out.println("Длительность между моментами времени: " + duration3);
// 3. Используйте метод parse() для создания из строки
Duration duration4 = Duration.parse("PT2H30M"); // Формат ISO-8601
System.out.println("Разобранная длительность: " + duration4);
// 4. Используйте Instant для вычисления разницы во времени
Instant startInstant = Instant.now();
// Имитация длительной операции
try { Thread.sleep(1500); } catch (InterruptedException e) {}
Instant endInstant = Instant.now();
Duration duration5 = Duration.between(startInstant, endInstant);
System.out.println("Длительность выполнения: " + duration5.toMillis() + "ms");
}
}
Результат вывода:
Duration 1: PT2H Duration 2: PT1H30M Duration between times: PT2H30M Parsed Duration: PT2H30M Execution duration: 1501ms
Примечания
Проблема точности: Duration может обеспечивать точность до наносекунд, но фактическая точность зависит от поддержки операционной системы и аппаратного обеспечения.
Отличие от Period:
- Duration используется для измерения временных значений: часов, минут, секунд и наносекунд
- Period используется для измерения календарных лет, месяцев и дней
Неизменяемость: Все объекты Duration неизменяемы; любая операция изменения возвращает новый экземпляр Duration.
Обработка отрицательных значений: Duration может представлять отрицательные интервалы времени, которые могут встретиться при вычислении разницы во времени.
Строковый формат: Использует формат длительности ISO-8601
PnDTnHnMn.nS, где:- P — это обозначение длительности
- D — количество дней
- T — разделитель для части времени
- H — количество часов
- M — количество минут
- S — количество секунд (может иметь дробную часть)
Итог
Класс Duration в Java предоставляет мощные и гибкие инструменты для работы с интервалами времени. Овладев использованием класса Duration, разработчики смогут легче решать различные задачи, связанные с вычислениями времени, такие как измерение производительности, контроль тайм-аутов, планирование задач и т. д. При совместном использовании с другими классами даты и времени, появившимися в Java 8 (такими как Instant, LocalDateTime и т. д.), класс Duration позволяет создавать более надёжный и читаемый код для работы со временем.
Другие расширения