Lớp java.time.Duration

Lớp Duration trong gói java.time của Java được sử dụng để biểu diễn một khoảng thời gian tính bằng giây và nano giây. Bạn có thể truy cập khoảng thời gian này theo các đơn vị khác như phút, giờ. Ngoài ra, đơn vị DAYS (ngày) có thể được sử dụng và được coi là chính xác bằng 24 giờ, bỏ qua tác động của giờ tiết kiệm ánh sáng (DST). Xem Period để biết lớp tương đương tính theo ngày.

Ⅰ. Đặc điểm của lớp Duration

Khoảng thời gian thực tế có thể có độ dài vô hạn. Tuy nhiên, vì mục đích thực tiễn, Duration được lưu trữ với các giới hạn tương tự như Instant (thời điểm).

Duration sử dụng độ phân giải nano giây với giá trị giây tối đa có thể lưu trữ trong một long (kiểu số nguyên 64 bit). Giá trị này lớn hơn cả tuổi ước tính hiện tại của vũ trụ.

Phạm vi của Duration yêu cầu lưu trữ một số lớn hơn long. Do đó, lớp lưu trữ một long biểu diễn giây và một int biểu diễn nano giây (từ 0 đến 999.999.999). Duration có thể là âm hoặc dương.

Đơn vị đo của Duration là "giây" nhưng không nhất thiết hoàn toàn giống với định nghĩa "giây SI" khoa học dựa trên đồng hồ nguyên tử. Sự khác biệt này chỉ ảnh hưởng đến các khoảng thời gian được đo gần giây nhuận và không ảnh hưởng đến hầu hết các ứng dụng. Xem Instant để biết thêm về ý nghĩa của giây và thang thời gian.

Duration là lớp dựa trên giá trị (value-based class); do đó, việc sử dụng các phép toán dựa trên định danh (identity-sensitive operations) như so sánh bằng (==), mã băm định danh (identity hash code) hoặc đồng bộ hóa trên các thể hiện của Duration có thể dẫn đến kết quả không mong đợi và nên tránh. Sử dụng phương thức equals để so sánh các Duration

Lớp Duration bất biến (immutable) và an toàn cho nhiều luồng (thread-safe).

Ⅱ. Khai báo lớp Duration trong Java

Để sử dụng lớp Duration và các lớp khác trong gói java.time, bạn cần thêm câu lệnh import vào đầu file Java của mình.

Cú pháp câu lệnh import:

Cú pháp

import java.time.Duration;

Cú pháp khai báo lớp Duration:

Cú pháp

public final class Duration
extends Object
implements TemporalAmount, Comparable<Duration>, Serializable

Dưới đây là giải thích chi tiết về cú pháp khai báo này:

↳ public: Lớp này có thể được truy cập từ bất kỳ đâu trong chương trình, không bị giới hạn phạm vi.

↳ final: Lớp này không thể bị kế thừa. Điều này có nghĩa là bạn không thể tạo một lớp con từ Duration.

↳ class Duration: Khai báo một lớp có tên là Duration.

↳ extends Object: Tất cả các lớp trong Java đều kế thừa từ lớp Object (lớp gốc của tất cả các lớp trong Java). Việc này cho phép lớp Duration kế thừa các phương thức cơ bản từ Object, chẳng hạn như toString(), equals(), và hashCode().

implements TemporalAmount, Comparable<Duration>, Serializable

Lớp Duration thực hiện (implements) các giao diện TemporalAmount, Comparable<Duration>, Serializable. Điều này có nghĩa là lớp Duration phải cung cấp các phương thức được khai báo trong những giao diện này.

↳ implements TemporalAmount: Lớp Duration thực hiện giao diện TemporalAmount, có nghĩa là nó có thể được sử dụng để đại diện cho một khoảng thời gian (thời gian trôi qua) và có thể thực hiện các phép toán liên quan đến thời gian.

↳ implements Comparable<Duration>: Lớp Duration thực hiện giao diện Comparable<Duration>, có nghĩa là bạn có thể so sánh các đối tượng Duration với nhau để xác định độ dài của chúng.

↳ implements Serializable: Lớp Duration thực hiện giao diện Serializable, có nghĩa là các đối tượng của lớp này có thể được tuần tự hóa (serialized) để lưu trữ hoặc truyền qua mạng.

Ⅲ. Các phương thức của lớp Duration

Lớp Duration cung cấp nhiều phương thức để thao tác với khoảng thời gian. Việc phân nhóm các phương thức theo chức năng sẽ giúp bạn hiểu rõ hơn về cách sử dụng lớp Duration. Dưới đây là cách phân nhóm các phương thức phổ biến của lớp Duration:

Tạo đối tượng Duration

↳ of(long amount, TemporalUnit unit): Tạo một Duration từ một giá trị và đơn vị thời gian.

↳ ofDays(), ofHours(), ofMillis(), ofMinutes(), ofNanos(), ofSeconds(): Các phương thức tiện ích để tạo Duration từ các đơn vị thời gian cụ thể.

Dưới đây là một ví dụ về cách sử dụng cả 7 phương thức để tạo đối tượng LocalDate trong cùng một lớp:

Ví dụ: Example.java

import java.time.Duration;

public class Example {
    public static void main(String[] args) {
        // Tạo Duration từ một giá trị và đơn vị thời gian
        Duration durationFromAmount = Duration.of(5, java.time.temporal.ChronoUnit.DAYS);
        System.out.println("Duration từ giá trị và đơn vị thời gian: " + durationFromAmount);

        // Tạo Duration từ các đơn vị thời gian cụ thể
        Duration durationFromDays = Duration.ofDays(10);
        System.out.println("Duration từ số ngày: " + durationFromDays);

        Duration durationFromHours = Duration.ofHours(3);
        System.out.println("Duration từ số giờ: " + durationFromHours);

        Duration durationFromMinutes = Duration.ofMinutes(45);
        System.out.println("Duration từ số phút: " + durationFromMinutes);

        Duration durationFromSeconds = Duration.ofSeconds(120);
        System.out.println("Duration từ số giây: " + durationFromSeconds);

        Duration durationFromMillis = Duration.ofMillis(500);
        System.out.println("Duration từ số mili giây: " + durationFromMillis);

        Duration durationFromNanos = Duration.ofNanos(1000000);
        System.out.println("Duration từ số nano giây: " + durationFromNanos);
    }
}

Kết quả của chương trình là:

Duration từ giá trị và đơn vị thời gian: PT120H
Duration từ số ngày: PT240H
Duration từ số giờ: PT3H
Duration từ số phút: PT45M
Duration từ số giây: PT2M
Duration từ số mili giây: PT0.5S
Duration từ số nano giây: PT0.001S

Trong ví dụ trên, mỗi phương thức được sử dụng để tạo một đối tượng Duration từ các đơn vị thời gian khác nhau và in ra kết quả để bạn có thể thấy cách chúng hoạt động.

Lấy thông tin

↳ toMinutes(): Lấy số phút trong Duration (bằng cách chia tổng số giây cho 60)

↳ isNegative(): Kiểm tra xem Duration có âm hay không.

↳ isZero(): Kiểm tra xem Duration có bằng 0 hay không.

↳ getNano(): Lấy số nano giây trong một giây của Duration.

↳ getSeconds(): Lấy số giây của Duration.

Dưới đây là ví dụ về việc sử dụng các phương thức toMinutes(), isNegative(), isZero(), getNano(), và getSeconds() từ lớp Duration trong một lớp Java:

Ví dụ: Example.java

import java.time.Duration;

public class Example {
    public static void main(String[] args) {
        // Tạo một Duration
        Duration duration = Duration.ofHours(2).plusMinutes(30).minusSeconds(45);

        // Lấy số phút trong Duration (bằng cách chia tổng số giây cho 60)
        long minutes = duration.toMinutes();
        System.out.println("Số phút trong Duration: " + minutes);

        // Kiểm tra xem Duration có âm hay không
        boolean isNegative = duration.isNegative();
        System.out.println("Duration có âm không: " + isNegative);

        // Kiểm tra xem Duration có bằng 0 hay không
        boolean isZero = duration.isZero();
        System.out.println("Duration có bằng 0 không: " + isZero);

        // Lấy số nano giây trong một giây của Duration
        int nanoSeconds = duration.getNano();
        System.out.println("Số nano giây trong một giây của Duration: " + nanoSeconds);

        // Lấy số giây của Duration
        long seconds = duration.getSeconds();
        System.out.println("Số giây của Duration: " + seconds);
    }
}

Kết quả của chương trình là:

Số phút trong Duration: 149
Duration có âm không: false
Duration có bằng 0 không: false
Số nano giây trong một giây của Duration: 0
Số giây của Duration: 8955

Trong ví dụ trên, các phương thức được sử dụng để lấy thông tin từ đối tượng Duration và in ra kết quả để bạn có thể thấy cách chúng hoạt động với các giá trị khác nhau của Duration.

So sánh và kiểm tra

↳ compareTo(Duration otherDuration): So sánh hai Duration với nhau.

↳ equals(Object obj): Kiểm tra xem hai Duration có bằng nhau hay không.

Dưới đây là một ví dụ về cách sử dụng các phương thức compareTo() và equals() của lớp Duration trong một lớp Java:

Ví dụ: Example.java

import java.time.Duration;

public class Example {
    public static void main(String[] args) {
        // Tạo hai đối tượng Duration
        Duration duration1 = Duration.ofHours(2).plusMinutes(30);
        Duration duration2 = Duration.ofHours(2).plusMinutes(30);
        Duration duration3 = Duration.ofHours(1).plusMinutes(45);

        // So sánh duration1 với duration2
        int comparisonResult = duration1.compareTo(duration2);
        if (comparisonResult == 0) {
            System.out.println("duration1 và duration2 bằng nhau.");
        } else if (comparisonResult > 0) {
            System.out.println("duration1 lớn hơn duration2.");
        } else {
            System.out.println("duration1 nhỏ hơn duration2.");
        }

        // Kiểm tra xem duration1 và duration2 có bằng nhau không
        boolean areEqual = duration1.equals(duration2);
        System.out.println("duration1 và duration2 có bằng nhau không: " + areEqual);

        // Kiểm tra xem duration1 và duration3 có bằng nhau không
        boolean areEqualDifferent = duration1.equals(duration3);
        System.out.println("duration1 và duration3 có bằng nhau không: " + areEqualDifferent);
    }
}

Kết quả của chương trình là:

duration1 và duration2 bằng nhau.
duration1 và duration2 có bằng nhau không: true
duration1 và duration3 có bằng nhau không: false

Trong ví dụ trên, phương thức compareTo được sử dụng để so sánh hai đối tượng Duration và xác định sự khác biệt về độ dài thời gian giữa chúng. Phương thức equals kiểm tra xem hai đối tượng Duration có bằng nhau hay không, dựa trên giá trị thời gian của chúng.

Điều chỉnh

↳ plus(Duration duration): Cộng thêm một Duration vào Duration hiện tại.

↳ minus(Duration duration): Trừ đi một Duration khỏi Duration hiện tại.

↳ abs(): Lấy giá trị tuyệt đối của Duration.

Dưới đây là ví dụ về cách sử dụng các phương thức plus(), minus(), và abs() của lớp Duration trong một lớp Java:

Ví dụ: Example.java

import java.time.Duration;

public class Example {
    public static void main(String[] args) {
        // Tạo một Duration cơ bản
        Duration baseDuration = Duration.ofHours(2).plusMinutes(30);

        // Tạo Duration thêm vào hoặc trừ đi
        Duration additionalDuration = Duration.ofMinutes(45);
        Duration subtractionDuration = Duration.ofMinutes(90);

        // Cộng thêm Duration vào Duration hiện tại
        Duration newDurationPlus = baseDuration.plus(additionalDuration);
        System.out.println("Sau khi cộng thêm: " + newDurationPlus);

        // Trừ Duration khỏi Duration hiện tại
        Duration newDurationMinus = baseDuration.minus(subtractionDuration);
        System.out.println("Sau khi trừ đi: " + newDurationMinus);

        // Lấy giá trị tuyệt đối của Duration
        Duration negativeDuration = Duration.ofMinutes(-120);
        Duration absoluteDuration = negativeDuration.abs();
        System.out.println("Giá trị tuyệt đối của Duration: " + absoluteDuration);
    }
}

Kết quả của chương trình là:

Sau khi cộng thêm: PT3H15M Ngày: 2024-07-22
Sau khi trừ đi: PT1H Ngày: 2024-07-22
Giá trị tuyệt đối của Duration: PT2H

Trong ví dụ trên, phương thức plus() được sử dụng để cộng thêm một khoảng thời gian vào đối tượng Duration hiện tại, phương thức minus để trừ một khoảng thời gian từ đối tượng Duration hiện tại, và phương thức abs để lấy giá trị tuyệt đối của đối tượng Duration.

Tính toán khoảng cách

↳ between(Temporal startInclusive, Temporal endExclusive): Tính khoảng thời gian giữa hai đối tượng thời gian.

Dưới đây là ví dụ về cách sử dụng phương thức between() của lớp Duration để tính toán khoảng thời gian giữa hai đối tượng Temporal:

Ví dụ: Example.java

import java.time.Duration;
import java.time.LocalDateTime;

public class Example {
    public static void main(String[] args) {
        // Tạo hai đối tượng LocalDateTime để xác định khoảng thời gian
        LocalDateTime start = LocalDateTime.of(2024, 7, 25, 9, 0); // Ngày 25 tháng 7 năm 2024, 09:00
        LocalDateTime end = LocalDateTime.of(2024, 7, 25, 17, 30); // Ngày 25 tháng 7 năm 2024, 17:30

        // Tính toán khoảng thời gian giữa hai LocalDateTime
        Duration duration = Duration.between(start, end);
        
        // Hiển thị kết quả
        System.out.println("Khoảng thời gian giữa hai thời điểm là: " + duration);
    }
}
 

Kết quả của chương trình là:

Khoảng thời gian giữa hai thời điểm là: PT8H30M

Trong ví dụ trên, phương thức between được sử dụng để tính toán khoảng thời gian giữa hai đối tượng LocalDateTime, và kết quả được in ra để hiển thị khoảng thời gian giữa hai thời điểm đó.

Áp dụng lên đối tượng thời gian

↳ addTo(Temporal temporal): Thêm Duration vào một đối tượng thời gian.

Dưới đây là ví dụ về cách sử dụng phương thức addTo của lớp Duration để thêm một khoảng thời gian (Duration) vào một đối tượng thời gian (Temporal), như LocalDateTime:

Ví dụ: Example.java

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.Temporal;

public class Example {
    public static void main(String[] args) {
        // Tạo đối tượng LocalDateTime đại diện cho thời điểm ban đầu
        LocalDateTime initialDateTime = LocalDateTime.of(2024, 7, 25, 9, 0); // Ngày 25 tháng 7 năm 2024, 09:00

        // Tạo một Duration đại diện cho khoảng thời gian cần thêm
        Duration duration = Duration.ofHours(5).plusMinutes(30); // 5 giờ 30 phút

        // Thêm Duration vào đối tượng LocalDateTime
        Temporal newDateTime = duration.addTo(initialDateTime);

        // Hiển thị kết quả
        System.out.println("Thời điểm sau khi thêm Duration là: " + newDateTime);
    }
}

Kết quả của chương trình là:

Thời điểm sau khi thêm Duration là: 2024-07-25T14:30

Trong ví dụ trên, phương thức addTo() được sử dụng để thêm một khoảng thời gian Duration vào một đối tượng LocalDateTime, và kết quả được in ra để hiển thị thời điểm mới sau khi thêm khoảng thời gian.

Các ngoại lệ thường gặp khi sử dụng lớp Duration trong Java

Dưới đây là các ngoại lệ thường gặp và nguyên nhân của chúng:

Ngoại lệ DateTimeException

↳ Nguyên nhân: Xảy ra khi bạn tạo một Duration với giá trị không hợp lệ, chẳng hạn như khi tổng số giờ, phút, giây, nano giây không khớp với một khoảng thời gian hợp lệ.

↳ Ví dụ: Khi bạn cố gắng tạo một Duration với giá trị giây âm mà không hợp lệ.

Ngoại lệ UnsupportedTemporalTypeException

↳ Nguyên nhân: Xảy ra khi bạn yêu cầu một đơn vị thời gian không được hỗ trợ từ một Duration

↳ Ví dụ: Khi bạn gọi get(ChronoUnit.MONTHS) trên một Duration, vì Duration không hỗ trợ đơn vị thời gian tháng.

Ngoại lệ ArithmeticException

↳ Nguyên nhân: Xảy ra khi thực hiện các phép toán với Duration có thể gây tràn số nguyên, ví dụ khi cộng thêm hoặc trừ đi quá nhiều thời gian.

↳ Ví dụ: Khi bạn cộng hai Duration có tổng số mili giây vượt quá giới hạn của số nguyên.

Lưu ý:

Khi làm việc với Duration, việc kiểm tra dữ liệu đầu vào và các thao tác ngày tháng là rất quan trọng để tránh các ngoại lệ. Sử dụng các phương pháp kiểm tra giá trị hợp lệ và xử lý các ngoại lệ như try-catch để xử lý ngoại lệ và cung cấp thông báo lỗi hoặc xử lý các tình huống bất thường để làm cho ứng dụng của bạn ổn định và dễ duy trì hơn.

Câu Nói Truyền Cảm Hứng

“Bắt đầu ở đâu không quan trọng, quan trọng là bạn sẵn sàng bắt đầu.” – W. Clement Stone

Không Gian Tích Cực

“Chúc bạn luôn giữ vững niềm tin và sức mạnh để vượt qua mọi thử thách trong cuộc sống.”