Lớp java.time.DayOfWeek

Lớp DayOfWeek trong gói java.time của Java là một kiểu liệt kê (enum) biểu diễn 7 ngày trong tuần: Thứ Hai, Thứ Ba, Thứ Tư, Thứ Năm, Thứ Sáu, Thứ Bảy và Chủ Nhật.

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

Mỗi ngày trong tuần có tên theo chữ (ví dụ: Thứ Hai) và một giá trị kiểu số nguyên (int).

Giá trị int tuân theo chuẩn ISO-8601, từ 1 (Thứ Hai) đến 7 (Chủ Nhật).

Nên sử dụng tên ngày trong tuần (enum) thay vì giá trị số int để đảm bảo mã dễ đọc.

DayOfWeek cung cấp phương thức để truy cập vào tên của ngày theo ngôn ngữ (ví dụ: "Thứ Hai" trong tiếng Việt).

Lưu ý rằng một số ngôn ngữ có thể đánh số thứ tự ngày trong tuần theo cách khác (ví dụ: Chủ Nhật là 1), nhưng DayOfWeek không hỗ trợ điều này. Sử dụng lớp WeekFields để lấy số thứ tự tuần theo ngôn ngữ.

Sử dụng phương thức getValue() để lấy giá trị số int của ngày trong tuần, không nên dùng phương thức ordinal().

DayOfWeek là một khái niệm chung trong nhiều hệ thống lịch. Do đó, nó có thể được sử dụng bởi bất kỳ hệ thống lịch nào có khái niệm ngày trong tuần tương đương với lịch ISO.

DayOfWeek là một kiểu liệt kê bất biến (immutable) và an toàn cho nhiều luồng (thread-safe).

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

Để sử dụng lớp DayOfWeek 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.DayOfWeek;

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

Cú pháp

public enum DayOfWeek
extends Enum<DayOfWeek>
implements TemporalAccessor, TemporalAdjuster

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.

↳ enum DayOfWeek: Đây là một enum (liệt kê) công khai có tên là DayOfWeek. enum là một kiểu dữ liệu đặc biệt dùng để định nghĩa một tập hợp các hằng số, và trong trường hợp này, DayOfWeek đại diện cho các ngày trong tuần (Chủ nhật, Thứ hai, ..., Thứ bảy).

extends Enum<DayOfWeek>: Điều này cho thấy DayOfWeek là một enum và kế thừa từ lớp Enum. Trong Java, tất cả các enum đều tự động kế thừa từ lớp Enum. Enum<DayOfWeek>chỉ định rằng DayOfWeek là một kiểu enum với các giá trị kiểu DayOfWeek.

implements TemporalAccessor, TemporalAdjuster

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

↳ implements TemporalAccessor: Giao diện này cho phép DayOfWeek truy cập các thông tin liên quan đến thời gian.

↳ implements TemporalAdjuster: Giao diện này cho phép DayOfWeek thực hiện các điều chỉnh liên quan đến thời gian, chẳng hạn như điều chỉnh ngày tháng.

Các hằng số Enum

DayOfWeek cung cấp các hằng số enum để biểu diễn các ngày cụ thể trong tuần:

↳ SUNDAY: Biểu diễn ngày Chủ Nhật.

↳ MONDAY: Biểu diễn ngày Thứ Hai.

↳ TUESDAY: Biểu diễn ngày Thứ Ba.

↳ WEDNESDAY: Biểu diễn ngày Thứ Tư.

↳ THURSDAY: Biểu diễn ngày Thứ Năm.

↳ FRIDAY: Biểu diễn ngày Thứ Sáu.

↳ SATURDAY: Biểu diễn ngày Thứ Bảy.

Lưu ý rằng mỗi hằng số này là một đối tượng duy nhất (singleton) đại diện cho ngày tương ứng trong tuần.

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

Lớp DayOfWeek cung cấp nhiều phương thức để thao tác với ngày trong tuần. 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 DayOfWeek. Dưới đây là cách phân nhóm các phương thức phổ biến của lớp DayOfWeek:

Tạo đối tượng DayOfWeek

↳ of(int dayOfWeek): Tạo một DayOfWeek từ một số nguyên biểu diễn thứ trong tuần.

↳ values(): Trả về một mảng chứa tất cả các giá trị có thể của DayOfWeek.

↳ valueOf(String name): Tạo một DayOfWeek từ tên của nó (ví dụ: "MONDAY").

Dưới đây là một ví dụ về cách sử dụng ba phương thức tạo đối trượng DayOfWeek trong một lớp Java:

Ví dụ: Example.java

import java.time.DayOfWeek;

public class Example {
    public static void main(String[] args) {
        // Tạo một DayOfWeek từ một số nguyên (1 đến 7)
        DayOfWeek day1 = DayOfWeek.of(1); // Chủ nhật
        DayOfWeek day2 = DayOfWeek.of(5); // Thứ năm
        
        // Hiển thị kết quả
        System.out.println("DayOfWeek.of(1): " + day1);
        System.out.println("DayOfWeek.of(5): " + day2);
        
        // Lấy tất cả các giá trị có thể của DayOfWeek
        DayOfWeek[] days = DayOfWeek.values();
        System.out.println("Tất cả các ngày trong tuần:");
        for (DayOfWeek day : days) {
            System.out.println(day);
        }
        
        // Tạo DayOfWeek từ tên của nó
        DayOfWeek monday = DayOfWeek.valueOf("MONDAY");
        System.out.println("DayOfWeek.valueOf(\"MONDAY\"): " + monday);
    }
}

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

DayOfWeek.of(1): MONDAY
DayOfWeek.of(5): FRIDAY
Tất cả các ngày trong tuần:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
DayOfWeek.valueOf("MONDAY"): MONDAY

Trong ví dụ trên, các phương thức được sử dụng để tạo đối tượng DayOfWeek từ số nguyên, lấy tất cả các giá trị có thể của DayOfWeek, và tạo đối tượng DayOfWeek từ tên của nó.

Lấy thông tin

↳ get(TemporalField field): Lấy giá trị của một trường thời gian cụ thể (như thứ trong tuần).

↳ getLong(TemporalField field): Giống get nhưng trả về giá trị kiểu long.

↳ getValue(): Lấy giá trị số nguyên biểu diễn thứ trong tuần.

↳ getDisplayName(TextStyle style, Locale locale): Lấy tên hiển thị của ngày trong tuần.

↳ isSupported(TemporalField field): Kiểm tra xem trường thời gian có được hỗ trợ hay không.e.

↳ range(TemporalField field): Lấy phạm vi các giá trị hợp lệ cho một trường thời gian.

Dưới đây là một ví dụ về cách sử dụng các phương thức của lớp DayOfWeek để lấy thông tin về ngày trong tuần trong Java:

Ví dụ: Example.java

import java.time.DayOfWeek;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.util.Locale;

public class Example {
    public static void main(String[] args) {
        // Tạo đối tượng DayOfWeek
        DayOfWeek day = DayOfWeek.WEDNESDAY;
        
        // Lấy giá trị của một trường thời gian cụ thể
        int dayValue = day.get(ChronoField.DAY_OF_WEEK);
        System.out.println("get(ChronoField.DAY_OF_WEEK): " + dayValue);
        
        // Lấy giá trị của trường thời gian dưới dạng long
        long dayValueLong = day.getLong(ChronoField.DAY_OF_WEEK);
        System.out.println("getLong(ChronoField.DAY_OF_WEEK): " + dayValueLong);
        
        // Lấy giá trị số nguyên biểu diễn thứ trong tuần
        int numericValue = day.getValue();
        System.out.println("getValue(): " + numericValue);
        
        // Lấy tên hiển thị của ngày trong tuần
        String displayName = day.getDisplayName(TextStyle.FULL, Locale.ENGLISH);
        System.out.println("getDisplayName(TextStyle.FULL, Locale.ENGLISH): " + displayName);
        
        // Kiểm tra xem trường thời gian có được hỗ trợ hay không
        boolean isSupported = day.isSupported(ChronoField.DAY_OF_WEEK);
        System.out.println("isSupported(ChronoField.DAY_OF_WEEK): " + isSupported);
        
        // Lấy phạm vi các giá trị hợp lệ cho một trường thời gian
        System.out.println("range(ChronoField.DAY_OF_WEEK): " + day.range(ChronoField.DAY_OF_WEEK));
    }
}

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

get(ChronoField.DAY_OF_WEEK): 3
getLong(ChronoField.DAY_OF_WEEK): 3
getValue(): 3
getDisplayName(TextStyle.FULL, Locale.ENGLISH): Wednesday
isSupported(ChronoField.DAY_OF_WEEK): true
range(ChronoField.DAY_OF_WEEK): 1 - 7

Trong ví dụ trên, các phương thức được sử dụng để lấy thông tin về DayOfWeek, bao gồm giá trị của trường thời gian, giá trị số nguyên, tên hiển thị, kiểm tra hỗ trợ, và phạm vi giá trị hợp lệ.

So sánh và kiểm tra

↳ compareTo(DayOfWeek other): So sánh hai DayOfWeek với nhau.

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

Dưới đây là ví dụ về cách sử dụng các phương thức compareTo() và phương thức equals() của lớp DayOfWeek để so sánh và kiểm tra ngày trong tuần:

Ví dụ: Example.java

import java.time.DayOfWeek;

public class Example {
    public static void main(String[] args) {
        // Tạo các đối tượng DayOfWeek
        DayOfWeek monday = DayOfWeek.MONDAY;
        DayOfWeek wednesday = DayOfWeek.WEDNESDAY;
        DayOfWeek anotherWednesday = DayOfWeek.WEDNESDAY;

        // So sánh hai DayOfWeek với nhau
        int comparisonResult = monday.compareTo(wednesday);
        System.out.println("compareTo(WEDNESDAY): " + comparisonResult); // Kết quả âm vì MONDAY trước WEDNESDAY

        // Kiểm tra hai DayOfWeek có bằng nhau không
        boolean isEqual = wednesday.equals(anotherWednesday);
        System.out.println("equals(another WEDNESDAY): " + isEqual); // Kết quả true vì cả hai đều là WEDNESDAY
    }
}

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

compareTo(WEDNESDAY): -2
equals(another WEDNESDAY): true

Trong ví dụ trên, phương thức compareTo() được sử dụng để so sánh hai đối tượng DayOfWeek và phương thức equals() để kiểm tra sự bằng nhau giữa hai đối tượng.

Điều chỉnh

↳ plus(long days): Cộng thêm một số ngày.

↳ minus(long days): Trừ đi một số ngày.

↳ with(Temporal temporal): Điều chỉnh đối tượng thời gian (Temporal) được cung cấp để có cùng ngày trong tuần với DayOfWeek hiện tại.

Dưới đây là ví dụ về cách sử dụng các phương thức plus(), minus() và adjustInto() của lớp DayOfWeek để điều chỉnh ngày trong tuần:

Ví dụ: Example.java

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;

public class Example {
    public static void main(String[] args) {
        // Tạo đối tượng DayOfWeek
        DayOfWeek dayOfWeek = DayOfWeek.MONDAY;

        // Cộng thêm một số ngày
        DayOfWeek newDayPlus = dayOfWeek.plus(3); // Tăng thêm 3 ngày
        System.out.println("plus(3 days): " + newDayPlus); // Kết quả: THURSDAY

        // Trừ đi một số ngày
        DayOfWeek newDayMinus = dayOfWeek.minus(2); // Giảm bớt 2 ngày
        System.out.println("minus(2 days): " + newDayMinus); // Kết quả: SATURDAY

        // Điều chỉnh một đối tượng thời gian khác về ngày trong tuần này
        LocalDate date = LocalDate.of(2024, 7, 22); // Ngày cụ thể
        // Điều chỉnh ngày trong tuần gần nhất của LocalDate
        LocalDate adjustedDate = date.with(TemporalAdjusters.next(dayOfWeek)); // Hoặc: date.with(TemporalAdjusters.previous(dayOfWeek))
        System.out.println("with(date): " + adjustedDate); // Kết quả: ngày thứ Hai gần nhất
    }
}

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

plus(3 days): THURSDAY
minus(2 days): SATURDAY
with(date): 2024-07-29

Trong ví dụ trên, phương thức plus() và minus() được sử dụng để điều chỉnh ngày trong tuần, còn with điều chỉnh một ngày cụ thể để nó trở thành ngày trong tuần mong muốn.

Truy vấn

↳ query(TemporalQuery query): Thực hiện một truy vấn tùy chỉnh trên DayOfWeek.

Dưới đây là ví dụ về cách sử dụng phương thức query() với TemporalQuery() trên đối tượng DayOfWeek:

Ví dụ: Example.java

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQuery;

public class Example {
    public static void main(String[] args) {
        // Tạo đối tượng DayOfWeek
        DayOfWeek dayOfWeek = DayOfWeek.WEDNESDAY;

        // Tạo một truy vấn tùy chỉnh để lấy số nguyên biểu diễn thứ trong tuần từ DayOfWeek
        TemporalQuery<Integer> query = new TemporalQuery<>() {
            @Override
            public Integer queryFrom(TemporalAccessor temporal) {
                if (temporal instanceof DayOfWeek) {
                    DayOfWeek dow = (DayOfWeek) temporal;
                    return dow.getValue(); // Trả về giá trị số nguyên của ngày trong tuần
                }
                return null;
            }
        };

        // Thực hiện truy vấn
        Integer dayOfWeekValue = dayOfWeek.query(query);
        System.out.println("Giá trị ngày trong tuần: " + dayOfWeekValue); // Kết quả: 3 (tương ứng với Wednesday)

        // Cũng có thể thực hiện truy vấn trên LocalDate
        LocalDate date = LocalDate.of(2024, 7, 24); // Ngày cụ thể (Wednesday)
        Integer dayOfWeekFromDate = date.query(query);
        System.out.println("Giá trị ngày trong tuần từ LocalDate: " + dayOfWeekFromDate); // Kết quả: 3
    }
}

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

Giá trị ngày trong tuần: 3
Giá trị ngày trong tuần từ LocalDate: null

Trong ví dụ trên, phương thức query() được sử dụng để thực hiện truy vấn tùy chỉnh để lấy giá trị số nguyên của ngày trong tuần từ đối tượng DayOfWeek và LocalDate.

Các ngoại lệ thường gặp khi sử dụng lớp DayOfWeek 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: Thường xảy ra khi bạn cung cấp một giá trị không hợp lệ cho DayOfWeek. Ví dụ, khi cố gắng tạo một DayOfWeek từ một số nguyên không nằm trong khoảng từ 1 đến 7.

↳ Ví dụ: Khi gọi phương thức DayOfWeek.of(8), sẽ xảy ra DateTimeException vì 8 không phải là một giá trị hợp lệ cho DayOfWeek.

Ngoại lệ UnsupportedTemporalTypeException

↳ Nguyên nhân: Xảy ra khi bạn cố gắng sử dụng một phương thức không hỗ trợ cho đối tượng DayOfWeek. Ví dụ, khi sử dụng phương thức get với một trường thời gian không hỗ trợ.

↳ Ví dụ: Khi gọi dayOfWeek.get(ChronoField.YEAR), bạn sẽ nhận được UnsupportedTemporalTypeException vì DayOfWeek không hỗ trợ trường thời gian YEAR.

Ngoại lệ ClassCastException

↳ Nguyên nhân: Xảy ra khi bạn thực hiện một phép chuyển kiểu không hợp lệ. Ví dụ, khi cố gắng chuyển một đối tượng TemporalAccessor không phải là DayOfWeek thành DayOfWeek.

↳ Ví dụ: Khi gọi DayOfWeek.MONDAY.query(temporal) và temporal không phải là một đối tượng DayOfWeek, sẽ xảy ra ClassCastException.

Ngoại lệ NullPointerException

↳ Nguyên nhân: Thường xảy ra khi bạn truyền giá trị null vào một phương thức yêu cầu một đối tượng không rỗng.

↳ Ví dụ: Khi gọi dayOfWeek.getDisplayName(null, Locale.ENGLISH) với tham số TextStyle là null, sẽ dẫn đến NullPointerException.

Lưu ý:

Khi làm việc với DayOfWeek, 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 cơ chế kiểm tra và xử lý ngoại lệ để 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.”