Lớp java.time.LocalDate
Lớp LocalDate trong gói java.time của Java được sử dụng để biểu diễn một ngày theo lịch ISO-8601, chẳng hạn như "2007-12-03". Nó là một đối tượng ngày-giờ không đổi (immutable) và lưu trữ thông tin ngày, tháng, năm. Bên cạnh đó, LocalDate cũng cung cấp các phương thức để truy cập các trường ngày khác như ngày trong năm, ngày trong tuần và tuần trong năm.
Ⅰ. Đặc điểm của lớp LocalDate
↳ Không lưu trữ hoặc biểu diễn thời gian hay múi giờ.
↳ Thích hợp để lưu trữ các ngày đơn lẻ như ngày sinh nhật.
↳ Không thể biểu diễn một thời điểm cụ thể mà cần thêm thông tin như sự lệch chuẩn hoặc múi giờ.
↳ Sử dụng lịch ISO-8601, hệ thống lịch dân dụng hiện đại được dùng ở hầu hết các quốc gia trên thế giới.
↳ Là lớp bất biến (immutable), các phép toán dựa trên sự so sánh bằng (==) hoặc sử dụng hash code không nên được áp dụng cho LocalDate. Bạn nên sử dụng phương thức equals để so sánh hai ngày.
↳ An toàn cho nhiều luồng (thread-safe).
↳ Tóm lại, LocalDate là một lớp hữu ích để làm việc với các ngày đơn lẻ theo lịch ISO-8601 mà không cần quan tâm đến thời gian hay múi giờ.
Ⅱ. Khai báo lớp LocalDate trong Java
Để sử dụng lớp LocalDate 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.LocalDate;
Cú pháp khai báo lớp LocalDate:
Cú pháp
public final class LocalDate
extends Object
implements Temporal, TemporalAdjuster, ChronoLocalDate, 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ừ LocalDate.
↳ class LocalDate: Khai báo một lớp có tên là LocalDate.
↳ 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 LocalDate 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, ChronoLocalDate, Serializable
Lớp LocalDate thực hiện (implements) các giao diện Temporal, TemporalAdjuster, ChronoLocalDate, và Serializable. Điều này có nghĩa là lớp LocalDate 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à một giao diện đại diện cho các đối tượng có thời gian như LocalDate, LocalTime, LocalDateTime. Nó định nghĩa các phương thức để truy cập và thao tác các trường thời gian.
↳ implements TemporalAdjuster:Là một giao diện cho phép điều chỉnh các giá trị thời gian cụ thể, như thay đổi ngày tháng, giờ phút. Ví dụ, nó có thể được sử dụng để tìm ngày thứ Hai tiếp theo hoặc ngày cuối cùng của tháng.
↳ implements ChronoLocalDate: Là một giao diện đại diện cho một ngày cụ thể trong một hệ thống lịch nào đó, chẳng hạn như hệ thống lịch ISO.
↳ implements Serializable: Là một giao diện đánh dấu cho biết các đối tượng của lớp này có thể được tuần tự hóa (serialize), nghĩa là có thể chuyển đổi thành một chuỗi byte để lưu trữ hoặc truyền qua mạng, và sau đó có thể khôi phục lại thành đối tượng ban đầu.
Ⅲ. Các phương thức của lớp LocalDate
Lớp LocalDate cung cấp nhiều phương thức hữu ích để thao tác với ngày tháng. 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 LocalDate. Dưới đây là cách phân nhóm các phương thức phổ biến của lớp LocalDate:
Tạo đối tượng LocalDate
↳ now(): Lấy ngày hiện tại.
↳ of(year, month, day): Tạo một LocalDate từ năm, tháng, ngày cụ thể.
↳ parse(CharSequence text): Phân tích một chuỗi biểu diễn ngày theo định dạng ISO 8601 để tạo một LocalDate.
↳ parse(CharSequence text, DateTimeFormatter formatter): Phân tích một chuỗi theo định dạng tùy chỉnh để tạo một LocalDate.
↳ ofYearDay(int year, int dayOfYear):Tạo một LocalDate từ năm và ngày trong năm.
Dưới đây là một ví dụ về cách sử dụng cả 5 phương thức để tạo đối tượng LocalDate trong cùng một lớp:
Ví dụ: Example.java
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Example {
public static void main(String[] args) {
// 1. now(): Lấy ngày hiện tại
LocalDate currentDate = LocalDate.now();
System.out.println("Ngày hiện tại: " + currentDate);
// 2. of(year, month, day): Tạo một LocalDate từ năm, tháng, ngày cụ thể
LocalDate specificDate = LocalDate.of(2023, 7, 21);
System.out.println("Tạo năm, tháng, ngày cụ thể: " + specificDate);
// 3. parse(CharSequence text): Phân tích một chuỗi biểu diễn ngày theo định dạng ISO 8601 để tạo một LocalDate
LocalDate isoParsedDate = LocalDate.parse("2023-07-21");
System.out.println("Phân tích ngày ISO: " + isoParsedDate);
// 4. parse(CharSequence text, DateTimeFormatter formatter): Phân tích một chuỗi theo định dạng tùy chỉnh để tạo một LocalDate
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate customParsedDate = LocalDate.parse("21/07/2023", customFormatter);
System.out.println("Tùy chỉnh định dạng ngày: " + customParsedDate);
// 5. ofYearDay(int year, int dayOfYear): Tạo một LocalDate từ năm và ngày trong năm
// Lưu ý: ngày thứ 202 của năm 2023 là ngày 21 tháng 7 năm 2023.
LocalDate dayOfYearDate = LocalDate.ofYearDay(2023, 202);
System.out.println("Ngày từ năm và ngày trong năm: " + dayOfYearDate);
}
}
Kết quả của chương trình là:
Tạo năm, tháng, ngày cụ thể: 2023-07-21
Phân tích ngày ISO: 2023-07-21
Tùy chỉnh định dạng ngày: 2023-07-21
Ngày từ năm và ngày trong năm: 2023-07-21
Trong ví dụ trên, mỗi phương thức đều được sử dụng để tạo ra một đối tượng LocalDate khác nhau và in ra kết quả để bạn có thể thấy sự khác biệt trong cách chúng hoạt động.
Truy xuất thông tin
↳ getYear(): Lấy năm.
↳ getMonth(): Lấy tháng.
↳ getDayOfMonth(): Lấy ngày trong tháng.
↳ getDayOfWeek(): Lấy ngày trong tuần.
↳ getDayOfYear(): Lấy ngày trong năm.
↳ getMonthValue(): Lấy giá trị tháng (1-12).
↳ isLeapYear(): Kiểm tra xem năm có phải là năm nhuận hay không.
↳ lengthOfMonth(): Trả về số ngày trong tháng của ngày hiện tại.
↳ lengthOfYear(): Trả về số ngày trong năm của ngày hiện tại.
Dưới đây là một ví dụ về cách sử dụng các phương thức truy xuất thông tin từ lớp LocalDate trong cùng một lớp:
Ví dụ: Example.java
import java.time.LocalDate;
import java.time.Month;
public class Example {
public static void main(String[] args) {
// Tạo một đối tượng LocalDate
LocalDate date = LocalDate.of(2024, 7, 22);
// 1. getYear(): Lấy năm
int year = date.getYear();
System.out.println("Năm: " + year);
// 2. getMonth(): Lấy tháng
Month month = date.getMonth();
System.out.println("Tháng: " + month); // Hoặc month.name() để lấy tên tháng
// 3. getDayOfMonth(): Lấy ngày trong tháng
int dayOfMonth = date.getDayOfMonth();
System.out.println("Ngày trong tháng: " + dayOfMonth);
// 4. getDayOfWeek(): Lấy ngày trong tuần
java.time.DayOfWeek dayOfWeek = date.getDayOfWeek();
System.out.println("Ngày trong tuần: " + dayOfWeek); // Hoặc dayOfWeek.name() để lấy tên ngày
// 5. getDayOfYear(): Lấy ngày trong năm
int dayOfYear = date.getDayOfYear();
System.out.println("Ngày trong năm: " + dayOfYear);
// 6. getMonthValue(): Lấy giá trị tháng (1-12)
int monthValue = date.getMonthValue();
System.out.println("Lấy giá trị tháng: " + monthValue);
// 7. isLeapYear(): Kiểm tra xem năm có phải là năm nhuận hay không
boolean isLeapYear = date.isLeapYear();
System.out.println("Có phải là năm nhuận hay không: " + isLeapYear);
// 8. lengthOfMonth(): Trả về số ngày trong tháng của ngày hiện tại
int lengthOfMonth = date.lengthOfMonth();
System.out.println("Số ngày trong tháng: " + lengthOfMonth);
// 9. lengthOfYear(): Trả về số ngày trong năm của ngày hiện tại
int lengthOfYear = date.lengthOfYear();
System.out.println("Số ngày trong năm: " + lengthOfYear);
}
}
Kết quả của chương trình là:
Tháng: JULY
Ngày trong tháng: 22
Ngày trong tuần: MONDAY
Ngày trong năm: 204
Lấy giá trị tháng: 7
Có phải là năm nhuận hay không: true
Số ngày trong tháng: 31
Số ngày trong năm: 366
Thay đổi giá trị
↳ plusDays(long daysToAdd): Cộng thêm một số ngày.
↳ minusDays(long daysToSubtract):Trừ đi một số ngày.
↳ plusMonths(long monthsToAdd): Cộng thêm một số tháng.
↳ minusMonths(long monthsToSubtract): Trừ đi một số tháng.
↳ withYear(year): Thay đổi năm.
↳ withMonth(month): Thay đổi tháng.
Dưới đây là một ví dụ về cách sử dụng các phương thức để thay đổi giá trị của đối tượng LocalDate trong cùng một lớp:
Ví dụ: Example.java
import java.time.LocalDate;
import java.time.Month;
public class Example {
public static void main(String[] args) {
// Tạo một đối tượng LocalDate
LocalDate date = LocalDate.of(2024, 7, 22);
System.out.println("Ngày ban đầu: " + date);
// 1. plusDays(long daysToAdd): Cộng thêm một số ngày
LocalDate datePlusDays = date.plusDays(10);
System.out.println("Ngày cộng 10 ngày: " + datePlusDays);
// 2. minusDays(long daysToSubtract): Trừ đi một số ngày
LocalDate dateMinusDays = date.minusDays(10);
System.out.println("Ngày trừ 10 ngày: " + dateMinusDays);
// 3. plusMonths(long monthsToAdd): Cộng thêm một số tháng
LocalDate datePlusMonths = date.plusMonths(3);
System.out.println("Ngày cộng 3 tháng: " + datePlusMonths);
// 4. minusMonths(long monthsToSubtract): Trừ đi một số tháng
LocalDate dateMinusMonths = date.minusMonths(3);
System.out.println("Ngày trừ 3 tháng: " + dateMinusMonths);
// 5. withYear(year): Thay đổi năm
LocalDate dateWithYear = date.withYear(2025);
System.out.println("Ngày với năm 2025: " + dateWithYear);
// 6. withMonth(month): Thay đổi tháng
LocalDate dateWithMonth = date.withMonth(Month.DECEMBER.getValue());
System.out.println("Ngày với tháng 12: " + dateWithMonth);
}
}
Kết quả của chương trình là:
Ngày cộng 10 ngày: 2024-08-01
Ngày trừ 10 ngày: 2024-07-12
Ngày cộng 3 tháng: 2024-10-22
Ngày trừ 3 tháng: 2024-04-22
Ngày với năm 2025: 2025-07-22
Ngày với tháng 12: 2024-12-22
Trong ví dụ trên, các phương thức này giúp bạn dễ dàng thao tác với các đối tượng LocalDate để thực hiện các phép cộng hoặc trừ ngày tháng, hoặc thay đổi các thành phần của ngày.
So sánh
↳ compareTo(ChronoLocalDate other): So sánh với một LocalDate khác.
↳ isBefore(ChronoLocalDate other): Kiểm tra xem có trước ngày khác hay không.
↳ isAfter(ChronoLocalDate other): Kiểm tra xem có sau ngày khác hay không.
↳ isEqual(Object obj): Kiểm tra xem có bằng với một đối tượng khác hay không.
Dưới đây là ví dụ về cách sử dụng các phương thức so sánh của lớp LocalDate:
Ví dụ: Example.java
import java.time.LocalDate;
public class Example {
public static void main(String[] args) {
// Tạo các đối tượng LocalDate để so sánh
LocalDate date1 = LocalDate.of(2024, 7, 22);
LocalDate date2 = LocalDate.of(2023, 12, 31);
LocalDate date3 = LocalDate.of(2024, 7, 22); // Ngày giống như date1
// 1. compareTo(ChronoLocalDate other): So sánh với một LocalDate khác
int comparisonResult1 = date1.compareTo(date2);
System.out.println("Kết quả so sánh date1 và date2: " + comparisonResult1);
// Kết quả dương nếu date1 sau date2, âm nếu date1 trước date2, và 0 nếu bằng nhau
// 2. isBefore(ChronoLocalDate other): Kiểm tra xem có trước ngày khác hay không
boolean isBefore = date1.isBefore(date2);
System.out.println("Ngày 1 có trước ngày 2 không? " + isBefore);
// Sẽ trả về true nếu date1 trước date2, ngược lại trả về false
// 3. isAfter(ChronoLocalDate other): Kiểm tra xem có sau ngày khác hay không
boolean isAfter = date1.isAfter(date2);
System.out.println("Date1 có sau date2 không? " + isAfter);
// Sẽ trả về true nếu date1 sau date2, ngược lại trả về false
// 4. isEqual(Object obj): Kiểm tra xem có bằng với một đối tượng khác hay không
boolean isEqual = date1.isEqual(date3);
System.out.println("Date1 có bằng date3 không? " + isEqual);
// Sẽ trả về true nếu date1 bằng date3, ngược lại trả về false
}
}
Kết quả của chương trình là:
Ngày 1 có trước ngày 2 không? false
Date1 có sau date2 không? true
Date1 có bằng date3 không? true
Định dạng:
↳ format(DateTimeFormatter formatter): Định dạng ngày thành một chuỗi theo mẫu cho trước.
Dưới đây là một ví dụ về cách sử dụng phương thức format(DateTimeFormatter formatter) trong lớp LocalDate để định dạng ngày thành một chuỗi theo mẫu cho trước:
Ví dụ: Example.java
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Example {
public static void main(String[] args) {
// Tạo một đối tượng LocalDate với ngày cụ thể
LocalDate date = LocalDate.of(2024, 7, 22);
// Tạo một DateTimeFormatter với định dạng mong muốn
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("dd/MM/yyyy");
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MMMM d, yyyy");
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// Định dạng ngày theo các mẫu khác nhau
String formattedDate1 = date.format(formatter1);
String formattedDate2 = date.format(formatter2);
String formattedDate3 = date.format(formatter3);
// In kết quả ra màn hình
System.out.println("Ngày định dạng theo mẫu dd/MM/yyyy: " + formattedDate1);
System.out.println("Ngày định dạng theo mẫu MMMM d, yyyy: " + formattedDate2);
System.out.println("Ngày định dạng theo mẫu yyyy-MM-dd: " + formattedDate3);
}
}
Kết quả của chương trình là:
Ngày định dạng theo mẫu MMMM d, yyyy: July 22, 2024
Ngày định dạng theo mẫu yyyy-MM-dd: 2024-07-22
Kết hợp với thời gian
↳ atTime(int hour, int minute): Kết hợp ngày với thời gian để tạo một LocalDateTime.
Dưới đây là ví dụ về cách sử dụng phương thức atTime(int hour, int minute) của lớp LocalDate để kết hợp ngày với thời gian và tạo ra một đối tượng LocalDateTime.
Ví dụ: Example.java
import java.time.LocalDate;
import java.time.LocalDateTime;
public class Example {
public static void main(String[] args) {
// Tạo một đối tượng LocalDate
LocalDate date = LocalDate.of(2024, 7, 22);
// Kết hợp ngày với thời gian để tạo một LocalDateTime
LocalDateTime dateTime = date.atTime(14, 30); // Kết hợp ngày với thời gian 14:30
// In kết quả ra màn hình
System.out.println("Ngày: " + date);
System.out.println("Ngày và giờ kết hợp: " + dateTime);
}
}
Kết quả của chương trình là:
Ngày và giờ kết hợp: 2024-07-22T14:30
Hy vọng ví dụ này giúp bạn hiểu cách kết hợp ngày và thời gian để tạo một đối tượng LocalDateTime trong Java!
Các ngoại lệ thường gặp khi sử dụng lớp LocalDate 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 có một thao tác không hợp lệ với ngày hoặc định dạng ngày không đúng.
↳ Ví dụ: Khi tạo đối tượng LocalDate với ngày không tồn tại, chẳng hạn như ngày 30 tháng 2.
Ngoại lệ DateTimeParseException
↳ Nguyên nhân: Xảy ra khi phân tích chuỗi ngày theo định dạng không hợp lệ.
↳ Ví dụ: Khi phân tích chuỗi ngày với định dạng không khớp với định dạng mong muốn.
Ngoại lệ NullPointerException
↳ Nguyên nhân: Xảy ra khi bạn cố gắng sử dụng một đối tượng LocalDate hoặc định dạng ngày mà nó là null.
↳ Ví dụ: Khi gọi phương thức trên một đối tượng LocalDate không được khởi tạo.
Ngoại lệ ArithmeticException
↳ Nguyên nhân: Xảy ra khi có phép toán không hợp lệ trong các phương thức liên quan đến ngày.
↳ Ví dụ: Khi thực hiện các phép toán vượt quá giới hạn của ngày.
Ngoại lệ IllegalArgumentException
↳ Nguyên nhân: Xảy ra khi tham số truyền vào không hợp lệ hoặc không được chấp nhận.
↳ Ví dụ: Khi tạo LocalDate với tham số tháng không hợp lệ.
Lưu ý:
Khi làm việc với LocalDate, 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 khối 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.