Lớp java.time.Year
Lớp Year trong gói java.time của Java được sử dụng để biểu diễn một năm trong hệ lịch ISO-8601 (ví dụ: 2007). Nó là một đối tượng ngày giờ bất biến (immutable) và cung cấp các phương thức để truy cập thông tin về năm.
Lưu ý về hệ lịch:
↳ Hệ lịch ISO-8601 chỉ tương thích hoàn toàn với hệ lịch Gregorian-Julian cho các năm gần đây. Một số vùng lãnh thổ của Nga đã chuyển sang hệ lịch Gregorian/ISO muộn hơn, đến tận năm 1920. Do đó, cần thận trọng khi xử lý các năm trong lịch sử.
↳ Lớp Year không lưu trữ hoặc biểu diễn tháng, ngày, thời gian hoặc múi giờ. Ví dụ, giá trị "2007" có thể được lưu trữ trong một đối tượng Year.
Ⅰ. Đặc điểm của lớp Year
↳ Năm được biểu diễn theo tiêu chuẩn ISO-8601 và sử dụng hệ thống đánh số kéo dài (proleptic numbering system). Năm 1 trước bởi năm 0, tiếp theo là năm -1.
↳ Hệ lịch ISO-8601 là hệ lịch dân dụng hiện đại được sử dụng phổ biến trên thế giới ngày nay. Nó tương đương với hệ lịch Gregorian kéo dài (proleptic Gregorian calendar system), trong đó các quy tắc tính toán năm nhuận hiện đại được áp dụng cho mọi thời đại. Đối với hầu hết các ứng dụng hiện đại, quy tắc ISO-8601 hoàn toàn phù hợp. Tuy nhiên, bất kỳ ứng dụng nào sử dụng ngày lịch sử và yêu cầu độ chính xác cao thì cách tiếp cận ISO-8601 có thể không phù hợp.
↳ Year 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 bản sắc (identity-sensitive operations) như so sánh bằng (==), mã băm bản sắc (identity hash code) hoặc đồng bộ hóa trên các thể hiện của Year 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 Year.
↳ Lớp Year bất biến (immutable) và an toàn cho nhiều luồng (thread-safe).
Ⅱ. Khai báo lớp Year trong Java
Để sử dụng lớp Year 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.Year;
Cú pháp khai báo lớp Year:
Cú pháp
public final class Year
extends Object
implements Temporal, TemporalAdjuster, Comparable<Year>, 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ừ Year.
↳ class Year: Khai báo một lớp có tên là Year.
↳ 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 Year kế thừa các phương thức cơ bản từ Object, chẳng hạn như toString(), equals(), và hashCode().
implements Temporal, TemporalAdjuster, Comparable<Year>, Serializable
Lớp Year thực hiện (implements) các giao diện implements Temporal, TemporalAdjuster, Comparable<Year>, Serializable . Điều này có nghĩa là lớp Year phải cung cấp các phương thức được khai báo trong những giao diện này.
↳ implements Temporal: Lớp Year thực hiện giao diện Temporal, nghĩa là nó cung cấp các phương thức để làm việc với ngày và giờ.
↳ implements TemporalAdjuster: Lớp Year cũng thực hiện giao diện TemporalAdjuster, cho phép điều chỉnh hoặc sửa đổi các đối tượng thời gian khác (như ngày hoặc tháng) dựa trên thông tin năm.
↳ implements Comparable<Year>: Lớp Year thực hiện giao diện Comparable, cho phép so sánh các đối tượng Year với nhau, tức là bạn có thể xác định xem một năm có sớm hơn, muộn hơn, hay bằng một năm khác.
↳ implements Serializable: Lớp Year thực hiện giao diện Serializable, nghĩa là đối tượng Year có thể được tuần tự hóa (serialized) và sau đó được khôi phục từ dạng tuần tự hóa (deserialized). Điều này là cần thiết khi bạn muốn lưu trữ hoặc truyền đối tượng Year qua mạng.
Ⅲ. Các phương thức của lớp Year
Lớp Year cung cấp nhiều phương thức để thao tác với năm. 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 Year. Dưới đây là cách phân nhóm các phương thức phổ biến của lớp Year:
Tạo đối tượng Year với LocalDate
↳ now(): Lấy năm hiện tại từ đồng hồ hệ thống theo múi giờ mặc định.
↳ atDay(int dayOfYear): Kết hợp năm với một ngày trong năm (dayOfYear) để tạo ra một đối tượng LocalDate (ngày tháng). Ví dụ, year.atDay(15) sẽ tạo ra ngày 15 tháng 1 của năm year.
Dưới đây là ví dụ về cách sử dụng hai phương thức atDay(int dayOfYear) và now() của lớp Year trong một lớp Java:
Ví dụ: Example.java
import java.time.LocalDate;
import java.time.Year;
public class Example {
public static void main(String[] args) {
// Tạo đối tượng Year với năm hiện tại
Year currentYear = Year.now();
// Kết hợp năm hiện tại với ngày trong năm để tạo ra LocalDate
LocalDate specificDate = currentYear.atDay(15); // Ngày 15 tháng 1 của năm hiện tại
// In kết quả ra màn hình
System.out.println("Năm hiện tại: " + currentYear);
System.out.println("Ngày cụ thể: " + specificDate);
}
}
Kết quả của chương trình là:
Ngày cụ thể: 2024-01-15
Trong ví dụ trên, phương thức now() được sử dụng để lấy năm hiện tại từ hệ thống, và phương thức atDay(int dayOfYear) kết hợp năm hiện tại với một ngày cụ thể trong năm để tạo ra một đối tượng LocalDate.
Kết hợp với thời gian
↳ get(TemporalField field): Lấy giá trị của một trường thời gian (TemporalField) cụ thể từ năm này dưới dạng số nguyên (int). Ví dụ: get(ChronoField.YEAR) sẽ trả về chính năm đó.
↳ isLeap(): Kiểm tra xem năm hiện tại có phải là năm nhuận theo hệ lịch ISO kéo dài (proleptic) hay không.
↳ length(): Lấy số ngày trong năm.
Dưới đây là ví dụ về cách sử dụng các phương thức get(TemporalField field), isLeap(), và length() của lớp Year trong một lớp Java:
Ví dụ: Example.java
import java.time.Year;
import java.time.temporal.ChronoField;
public class Example {
public static void main(String[] args) {
// Tạo đối tượng Year với năm hiện tại
Year currentYear = Year.now();
// Lấy giá trị của trường năm (ChronoField.YEAR)
int yearValue = currentYear.get(ChronoField.YEAR);
// Kiểm tra xem năm hiện tại có phải là năm nhuận không
boolean isLeapYear = currentYear.isLeap();
// Lấy số ngày trong năm
int daysInYear = currentYear.length();
// In kết quả ra màn hình
System.out.println("Năm hiện tại: " + yearValue);
System.out.println("Năm hiện tại có phải là năm nhuận không: " + isLeapYear);
System.out.println("Số ngày trong năm hiện tại: " + daysInYear);
}
}
Kết quả của chương trình là:
Năm hiện tại có phải là năm nhuận không: true
Số ngày trong năm hiện tại: 366
Trong ví dụ trên, phương thức get(ChronoField.YEAR) được sử dụng để lấy giá trị năm hiện tại, phương thức isLeap() kiểm tra xem năm hiện tại có phải là năm nhuận hay không, và phương thức length() lấy số ngày trong năm hiện tại.
So sánh năm
↳ isAfter(Year other): Kiểm tra xem năm này có sau năm other hay không.
↳ isBefore(Year other): Kiểm tra xem năm này có trước năm other hay không.
Dưới đây là ví dụ về cách sử dụng các phương thức isAfter(Year other) và isBefore(Year other) của lớp Year trong một lớp Java:
Ví dụ: Example.java
import java.time.Year;
public class Example {
public static void main(String[] args) {
// Tạo các đối tượng Year để so sánh
Year year2020 = Year.of(2020);
Year year2021 = Year.of(2021);
Year year2022 = Year.of(2022);
// So sánh các năm
boolean is2021After2020 = year2021.isAfter(year2020);
boolean is2020Before2021 = year2020.isBefore(year2021);
// In kết quả ra màn hình
System.out.println("2021 có sau 2020 không: " + is2021After2020);
System.out.println("2020 có trước 2021 không: " + is2020Before2021);
}
}
Kết quả của chương trình là:
2020 có trước 2021 không: true
Trong ví dụ trên, phương thức isAfter(Year other) được sử dụng để kiểm tra xem năm 2021 có sau năm 2020 hay không, và phương thức isBefore(Year other) được sử dụng để kiểm tra xem năm 2020 có trước năm 2021 hay không.
Định dạng năm
↳ format(DateTimeFormatter formatter): Định dạng năm theo bộ định dạng (DateTimeFormatter) được cung cấp.
Dưới đây là ví dụ về cách sử dụng phương thức format(DateTimeFormatter formatter) của lớp Year trong một lớp Java:
Ví dụ: Example.java
import java.time.Year;
import java.time.format.DateTimeFormatter;
public class Example {
public static void main(String[] args) {
// Tạo đối tượng Year
Year year = Year.of(2024);
// Tạo bộ định dạng cho năm
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy");
// Định dạng năm theo bộ định dạng đã cho
String formattedYear = year.format(formatter);
// In kết quả ra màn hình
System.out.println("Năm đã định dạng: " + formattedYear);
}
}
Kết quả của chương trình là:
Trong ví dụ trên, phương thức format(DateTimeFormatter formatter) được sử dụng để định dạng năm 2024 theo mẫu định dạng yyyy. Kết quả được in ra màn hình là "Năm đã định dạng: 2024".
Các ngoại lệ thường gặp khi sử dụng lớp Year 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: Khi bạn cố gắng tạo một đối tượng Year với giá trị năm không hợp lệ, chẳng hạn như năm âm hoặc năm quá lớn.
↳ Ví dụ: Thử tạo một đối tượng Year với giá trị năm âm như -500.
Ngoại lệ UnsupportedTemporalTypeException
↳ Nguyên nhân: Khi gọi các phương thức yêu cầu trường thời gian mà Year không hỗ trợ, chẳng hạn như trường "giây" hoặc "phút".
↳ Ví dụ: Thử lấy giá trị của trường ChronoField.SECOND_OF_MINUTE từ một đối tượng Year.
Ngoại lệ IllegalArgumentException
↳ Nguyên nhân: Khi truyền vào các tham số không hợp lệ cho các phương thức, chẳng hạn như một ngày không hợp lệ trong năm.
↳ Ví dụ: Thử tạo ngày không hợp lệ như ngày 366 trong một năm không phải năm nhuận.
Lưu ý:
Khi làm việc với Year, 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 thức kiểm tra hợp lệ và xử lý ngoại lệ như try-catch để 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.