1. LocalDate: ngày không có thời gian và múi giờ
LocalDate — chỉ là một ngày. Không có thời gian, không có múi giờ, không rắc rối. Như một tờ lịch: 2025-06-01 — thế là xong. Nếu bạn không quan tâm chính xác “nửa đêm” là lúc nào ở các thành phố khác nhau, mà chỉ cần “01 tháng 6 năm 2025” — hãy dùng LocalDate.
Tạo LocalDate như thế nào?
Có vài cách, tất cả đều đơn giản và tiện lợi.
Ngày hiện tại
import java.time.LocalDate;
LocalDate today = LocalDate.now();
System.out.println(today); // Ví dụ: 2025-06-01
Ngày cụ thể
LocalDate birthday = LocalDate.of(1990, 12, 15);
System.out.println(birthday); // 1990-12-15
Bạn có thể dùng số cho năm, tháng và ngày. Tháng là số từ 1 đến 12 (tháng 1 — 1, tháng 12 — 12).
Parse từ chuỗi
LocalDate parsedDate = LocalDate.parse("2025-06-01");
System.out.println(parsedDate); // 2025-06-01
Chuỗi phải theo định dạng yyyy-MM-dd. Nếu định dạng không khớp — sẽ ném ngoại lệ.
Lấy các thành phần của ngày
LocalDate có các phương thức trả về từng phần của ngày:
int year = today.getYear(); // 2025
int month = today.getMonthValue(); // 6 (tháng 6)
int day = today.getDayOfMonth(); // 1
System.out.println("Năm: " + year + ", tháng: " + month + ", ngày: " + day);
Nếu muốn lấy tên tháng dạng chữ, dùng phương thức getMonth():
System.out.println(today.getMonth()); // JUNE
Còn nếu cần ngày trong tuần — dùng phương thức getDayOfWeek():
System.out.println(today.getDayOfWeek()); // SATURDAY
Ví dụ thực tế
Tiếp tục phát triển ứng dụng console học tập của bạn: giờ nó có thể chúc mừng sinh nhật người dùng.
import java.time.LocalDate;
public class BirthdayApp {
public static void main(String[] args) {
LocalDate birthday = LocalDate.of(2000, 2, 29);
System.out.println("Ngày sinh: " + birthday);
System.out.println("Ngày trong tuần của ngày sinh: " + birthday.getDayOfWeek());
}
}
2. LocalTime: thời gian không có ngày và múi giờ
LocalTime — chỉ là thời gian. Giờ, phút, giây (thậm chí nano giây). Nhưng không có ngày! Nếu cần lưu, chẳng hạn, “giờ mở cửa của cửa hàng” hoặc “giờ bắt đầu cuộc họp” mà không gắn với ngày — đây là lớp bạn cần.
Tạo LocalTime như thế nào?
Thời gian hiện tại
import java.time.LocalTime;
LocalTime now = LocalTime.now();
System.out.println(now); // Ví dụ: 14:37:12.123456789
Thời gian cụ thể
LocalTime lunchTime = LocalTime.of(13, 30); // 13:30:00
System.out.println(lunchTime);
Bạn có thể thêm giây và nano giây:
LocalTime precise = LocalTime.of(8, 15, 30, 123_000_000); // 08:15:30.123
System.out.println(precise);
Parse từ chuỗi
LocalTime parsedTime = LocalTime.parse("14:30:00");
System.out.println(parsedTime); // 14:30
Lấy các thành phần của thời gian
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
System.out.println("Giờ: " + hour + ", phút: " + minute + ", giây: " + second);
Ví dụ thực tế
Thêm “đồng hồ” vào ứng dụng của chúng ta:
import java.time.LocalTime;
public class ClockApp {
public static void main(String[] args) {
LocalTime current = LocalTime.now();
System.out.println("Bây giờ: " + current);
System.out.println("Giờ: " + current.getHour());
System.out.println("Phút: " + current.getMinute());
}
}
3. LocalDateTime: ngày và giờ không có múi giờ
LocalDateTime — là combo: ngày + giờ, nhưng vẫn không có múi giờ. Ví dụ, “2025-06-01 14:30:00”. Rất tiện khi bạn muốn lưu một thời điểm nhưng không quan tâm nó sẽ được đọc ở đâu trên thế giới.
Tạo LocalDateTime như thế nào?
Ngày và giờ hiện tại
import java.time.LocalDateTime;
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // Ví dụ: 2025-06-01T14:30:15.123456789
Ngày và giờ cụ thể
LocalDateTime meeting = LocalDateTime.of(2025, 6, 1, 14, 30);
System.out.println(meeting); // 2025-06-01T14:30
Bạn có thể thêm giây và nano giây:
LocalDateTime preciseMeeting = LocalDateTime.of(2025, 6, 1, 14, 30, 45, 123_000_000);
System.out.println(preciseMeeting); // 2025-06-01T14:30:45.123
Parse từ chuỗi
LocalDateTime parsed = LocalDateTime.parse("2025-06-01T14:30:00");
System.out.println(parsed); // 2025-06-01T14:30
Lưu ý: chữ T tách ngày và thời gian theo chuẩn ISO.
Lấy các thành phần
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
int minute = now.getMinute();
System.out.println("Ngày: " + year + "-" + month + "-" + day + " Thời gian: " + hour + ":" + minute);
4. Những thao tác thường gặp với ngày và giờ
Bây giờ khi đã biết tạo đối tượng ngày và giờ, hãy học cách làm những việc hữu ích với chúng.
Cộng và trừ
Cả ba lớp (LocalDate, LocalTime, LocalDateTime) đều bất biến. Nghĩa là các phương thức như plusDays() hoặc minusMonths() trả về một đối tượng mới, không thay đổi đối tượng gốc.
LocalDate
LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
LocalDate lastMonth = today.minusMonths(1);
System.out.println("Hôm nay: " + today);
System.out.println("Ngày mai: " + tomorrow);
System.out.println("Một tháng trước: " + lastMonth);
LocalTime
LocalTime now = LocalTime.now();
LocalTime inTenMinutes = now.plusMinutes(10);
System.out.println("Bây giờ: " + now);
System.out.println("Sau 10 phút: " + inTenMinutes);
LocalDateTime
LocalDateTime start = LocalDateTime.of(2025, 6, 1, 14, 0);
LocalDateTime end = start.plusHours(2).minusMinutes(15);
System.out.println("Bắt đầu: " + start);
System.out.println("Kết thúc: " + end);
So sánh ngày và giờ
Tất cả các lớp đều có các phương thức isBefore(), isAfter(), isEqual():
LocalDate birthday = LocalDate.of(2000, 2, 29);
LocalDate today = LocalDate.now();
if (today.isAfter(birthday)) {
System.out.println("Bạn không còn vừa mới sinh nữa!");
}
LocalTime morning = LocalTime.of(8, 0);
LocalTime now = LocalTime.now();
if (now.isBefore(morning)) {
System.out.println("Còn quá sớm để dậy...");
} else {
System.out.println("Đến giờ thức dậy!");
}
Lấy ngày/giờ hiện tại
Như bạn đã thấy, các phương thức now() trả về giá trị hiện tại:
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
5. Thực hành: ví dụ và bài tập
Ví dụ 1: Ngày trong tuần cho bất kỳ ngày nào
import java.time.LocalDate;
public class DayOfWeekApp {
public static void main(String[] args) {
LocalDate anyDate = LocalDate.of(2025, 12, 31);
System.out.println("31 tháng 12 năm 2025 — là " + anyDate.getDayOfWeek());
}
}
Ví dụ 2: Còn bao nhiêu ngày đến Năm Mới?
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class DaysToNewYear {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalDate newYear = LocalDate.of(today.getYear() + 1, 1, 1);
long daysLeft = ChronoUnit.DAYS.between(today, newYear);
System.out.println("Còn " + daysLeft + " ngày nữa là đến Năm Mới!");
}
}
Ví dụ 3: Kiểm tra năm nhuận hay không
import java.time.LocalDate;
public class LeapYearCheck {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 1, 1);
if (date.isLeapYear()) {
System.out.println(date.getYear() + " — là năm nhuận!");
} else {
System.out.println(date.getYear() + " — là năm thường.");
}
}
}
Ví dụ 4: Chênh lệch giữa hai thời điểm
import java.time.LocalTime;
import java.time.Duration;
public class TimeDifference {
public static void main(String[] args) {
LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(17, 30);
Duration duration = Duration.between(start, end);
System.out.println("Một ngày làm việc kéo dài " + duration.toHours() + " giờ " +
(duration.toMinutes() % 60) + " phút.");
}
}
6. Lỗi điển hình
Lỗi số 1: Nhầm lẫn giữa LocalDateTime và ZonedDateTime.
LocalDateTime không chứa thông tin về múi giờ! Nếu bạn lưu lịch bay giữa các quốc gia hoặc sự kiện diễn ra ở các vùng khác nhau — hãy dùng ZonedDateTime, nếu không có thể nhận kết quả bất ngờ khi chuyển dữ liệu giữa các hệ thống.
Lỗi số 2: Dùng định dạng chuỗi không đúng để parse.
Ví dụ, cố parse 01.06.2025 bằng LocalDate.parse(). Mặc định mong đợi định dạng 2025-06-01. Với các định dạng khác, cần DateTimeFormatter chuyên biệt (sẽ nói trong bài giảng tiếp theo!).
Lỗi số 3: Nghĩ rằng các phương thức như plusDays() làm thay đổi đối tượng.
Không! Tất cả đối tượng đều bất biến. Phương thức trả về một đối tượng mới, đối tượng cũ giữ nguyên.
Lỗi số 4: Dùng LocalTime để lưu thời gian tuyệt đối.
LocalTime — chỉ dành cho thời gian trong ngày tại địa phương. Nếu bạn muốn lưu “một khoảnh khắc trong thời gian”, hãy dùng Instant hoặc ZonedDateTime.
Lỗi số 5: Quên quy ước về tháng (1 — tháng 1, 12 — tháng 12).
Trong LocalDate.of(year, month, day), tháng được tính từ 1 (không phải từ 0 như ở một số ngôn ngữ khác hoặc API cũ).
GO TO FULL VERSION