Java 8 - API Ngày và Giờ Mới
Xin chào các pháp sư Java tương lai! ? Hôm nay, chúng ta sẽ bắt đầu một hành trình thú vị qua thế giới kỳ diệu của API Ngày và Giờ của Java. Đừng lo nếu bạn chưa từng viết một dòng mã trước đây - chúng ta sẽ bắt đầu từ những điều cơ bản và cùng nhau tiến hóa. Đến cuối bài học này, bạn sẽ có thể xử lý ngày và giờ như một chuyên gia! Hãy cùng lặn xuống!
Giới thiệu về API Ngày và Giờ của Java
Hãy tưởng tượng bạn đang xây dựng một máy thời gian (thật tuyệt phải không?). Để làm cho nó hoạt động, bạn cần xử lý ngày và giờ một cách chính xác. Đó chính xác là điều mà API Ngày và Giờ của Java giúp chúng ta làm trong các chương trình của mình. Nó giống như có một đồng hồ và lịch siêu chính xác gộp lại thành một!
Tại sao lại có một API mới?
Trước khi chúng ta đi vào chi tiết, bạn có thể đang tự hỏi, "Tại sao Java lại tạo ra một API Ngày và Giờ mới?" Hãy để tôi kể cho bạn một câu chuyện ngắn.
Ngày xưa (trước Java 8), các nhà phát triển phải sử dụng các lớp cũ java.util.Date
và java.util.Calendar
. Những lớp này giống như sử dụng một đồng hồ cũ, rỉ sét - chúng hoạt động, nhưng chúng có rất nhiều vấn đề. Chúng khó sử dụng, không an toàn cho đa luồng (tức là chúng có thể gây ra vấn đề trong các chương trình phức tạp), và không xử lý giờ múi giờ tốt.
Vì vậy, đội ngũ Java đã quyết định tạo ra một API mới, sáng bóng để giải quyết tất cả những vấn đề này. Và thế là gói java.time
ra đời trong Java 8!
API Ngày và Giờ Cục bộ của Java
Hãy bắt đầu từ những điều cơ bản. API Ngày và Giờ Cục bộ giúp chúng ta làm việc với ngày và giờ mà không cần quan tâm đến múi giờ. Nó giống như có một đồng hồ và lịch đơn giản trên bàn của bạn.
LocalDate
LocalDate
đại diện cho một ngày mà không có múi giờ. Hãy xem cách sử dụng nó:
import java.time.LocalDate;
public class DateExample {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
System.out.println("Ngày hôm nay là: " + today);
LocalDate specificDate = LocalDate.of(2023, 6, 15);
System.out.println("Một ngày cụ thể: " + specificDate);
}
}
Trong ví dụ này, chúng ta đang làm hai việc:
- Lấy ngày hiện tại sử dụng
LocalDate.now()
. - Tạo một ngày cụ thể (ngày 15 tháng 6 năm 2023) sử dụng
LocalDate.of()
.
Khi bạn chạy đoạn mã này, bạn sẽ thấy ngày hiện tại và ngày cụ thể chúng ta đã tạo được in ra.
LocalTime
LocalTime
đại diện cho một thời gian mà không có ngày hoặc múi giờ. Dưới đây là cách chúng ta có thể sử dụng nó:
import java.time.LocalTime;
public class TimeExample {
public static void main(String[] args) {
LocalTime now = LocalTime.now();
System.out.println("Thời gian hiện tại là: " + now);
LocalTime specificTime = LocalTime.of(14, 30, 45);
System.out.println("Một thời gian cụ thể: " + specificTime);
}
}
Trong ví dụ này:
- Lấy thời gian hiện tại sử dụng
LocalTime.now()
. - Tạo một thời gian cụ thể (2:30:45 PM) sử dụng
LocalTime.of()
.
LocalDateTime
LocalDateTime
kết hợp cả ngày và giờ, nhưng vẫn không có múi giờ. Nó giống như một đồng hồ có cả ngày và giờ. Dưới đây là cách sử dụng nó:
import java.time.LocalDateTime;
public class DateTimeExample {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
System.out.println("Ngày và giờ hiện tại: " + now);
LocalDateTime specificDateTime = LocalDateTime.of(2023, 6, 15, 14, 30, 45);
System.out.println("Một ngày và giờ cụ thể: " + specificDateTime);
}
}
Trong ví dụ này:
- Lấy ngày và giờ hiện tại sử dụng
LocalDateTime.now()
. - Tạo một ngày và giờ cụ thể (ngày 15 tháng 6 năm 2023, lúc 2:30:45 PM) sử dụng
LocalDateTime.of()
.
API Ngày và Giờ Múi giờ của Java
Bây giờ, hãy thêm một chút gia vị vào máy thời gian của chúng ta - múi giờ! API Ngày và Giờ Múi giờ giúp chúng ta làm việc với ngày và giờ trong các múi giờ khác nhau.
ZonedDateTime
ZonedDateTime
đại diện cho một ngày và giờ có múi giờ. Nó giống như một đồng hồ thế giới hiển thị các thời gian khác nhau cho các phần khác nhau của thế giới.
import java.time.ZonedDateTime;
import java.time.ZoneId;
public class ZonedDateTimeExample {
public static void main(String[] args) {
ZonedDateTime nowInSystemTZ = ZonedDateTime.now();
System.out.println("Ngày và giờ hiện tại trong múi giờ hệ thống: " + nowInSystemTZ);
ZonedDateTime nowInParis = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
System.out.println("Ngày và giờ hiện tại ở Paris: " + nowInParis);
}
}
Trong ví dụ này:
- Lấy ngày và giờ hiện tại trong múi giờ mặc định của hệ thống sử dụng
ZonedDateTime.now()
. - Lấy ngày và giờ hiện tại ở Paris sử dụng
ZonedDateTime.now(ZoneId.of("Europe/Paris"))
.
Enum ChronoUnits của Java
Enum ChronoUnit
cung cấp một bộ các đơn vị thời gian và chu kỳ tiêu chuẩn. Nó giống như có các công cụ đo lường khác nhau cho thời gian - giây, phút, giờ, ngày, tuần, tháng, năm, và vân vân.
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
public class ChronoUnitExample {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime futureDateTime = now.plus(1, ChronoUnit.WEEKS);
long daysBetween = ChronoUnit.DAYS.between(now, futureDateTime);
System.out.println("Số ngày giữa hiện tại và một tuần sau: " + daysBetween);
}
}
Trong ví dụ này:
- Thêm một tuần vào ngày và giờ hiện tại sử dụng
plus(1, ChronoUnit.WEEKS)
. - Tính toán số ngày giữa hiện tại và một tuần sau sử dụng
ChronoUnit.DAYS.between()
.
Java Period và Duration
Period
và Duration
được sử dụng để đại diện cho lượng thời gian. Hãy tưởng tượng Period
là sự khác biệt giữa hai ngày trên lịch, và Duration
là thời gian hiển thị trên một đồng hồ bấm giờ.
import java.time.LocalDate;
import java.time.Period;
import java.time.Duration;
import java.time.LocalTime;
public class PeriodDurationExample {
public static void main(String[] args) {
LocalDate date1 = LocalDate.of(2023, 1, 1);
LocalDate date2 = LocalDate.of(2023, 12, 31);
Period period = Period.between(date1, date2);
System.out.println("Khoảng thời gian giữa " + date1 + " và " + date2 + ": " + period);
LocalTime time1 = LocalTime.of(9, 0);
LocalTime time2 = LocalTime.of(17, 30);
Duration duration = Duration.between(time1, time2);
System.out.println("Thời gian giữa " + time1 + " và " + time2 + ": " + duration);
}
}
Trong ví dụ này:
- Tính toán khoảng thời gian giữa hai ngày sử dụng
Period.between()
. - Tính toán thời gian giữa hai thời gian sử dụng
Duration.between()
.
Java Temporal Adjusters
Temporal Adjusters giống như những cây phép cho ngày. Chúng cho phép bạn điều chỉnh ngày theo những cách hữu ích, như tìm ngày thứ Hai tiếp theo hoặc ngày cuối cùng của tháng.
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
public class TemporalAdjustersExample {
public static void main(String[] args) {
LocalDate date = LocalDate.now();
LocalDate nextMonday = date.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
System.out.println("Ngày thứ Hai tiếp theo: " + nextMonday);
LocalDate lastDayOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("Ngày cuối cùng của tháng này: " + lastDayOfMonth);
}
}
Trong ví dụ này:
- Tìm ngày thứ Hai tiếp theo sử dụng
TemporalAdjusters.next(DayOfWeek.MONDAY)
. - Tìm ngày cuối cùng của tháng hiện tại sử dụng
TemporalAdjusters.lastDayOfMonth()
.
Tương thích ngược
Bây giờ, bạn có thể đang tự hỏi, "Vậy tất cả các đoạn mã cũ sử dụng các lớp ngày và giờ cũ thì sao?" Đừng lo lắng! Java đã suy nghĩ đến điều đó. API mới cung cấp các phương thức để chuyển đổi giữa các lớp ngày và giờ cũ và mới.
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
public class BackwardCompatibilityExample {
public static void main(String[] args) {
// Chuyển đổi từ Date cũ sang LocalDateTime mới
Date oldDate = new Date();
LocalDateTime newDateTime = LocalDateTime.ofInstant(oldDate.toInstant(), ZoneId.systemDefault());
System.out.println("Date cũ: " + oldDate);
System.out.println("LocalDateTime mới: " + newDateTime);
// Chuyển đổi từ LocalDateTime mới sang Date cũ
LocalDateTime localDateTime = LocalDateTime.now();
Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
System.out.println("LocalDateTime mới: " + localDateTime);
System.out.println("Date cũ: " + date);
}
}
Trong ví dụ này:
- Chuyển đổi một đối tượng
Date
cũ sangLocalDateTime
mới. - Chuyển đổi một đối tượng
LocalDateTime
mới sangDate
cũ.
Tương thích ngược này đảm bảo rằng bạn vẫn có thể làm việc với mã Java cũ trong khi tận hưởng lợi ích của API Ngày và Giờ mới.
Kết luận
Chúc mừng! Bạn đã迈出了 những bước đầu tiên vào thế giới của API Ngày và Giờ của Java. Chúng ta đã bao quát rất nhiều nội dung, từ việc xử lý ngày và giờ cơ bản đến các khái niệm phức tạp hơn như múi giờ và temporal adjusters.
Nhớ rằng, như bất kỳ kỹ năng nào khác, việc thành thạo ngày và giờ trong Java đòi hỏi sự thực hành. Đừng nản lòng nếu cảm thấy quá tải ban đầu - ngay cả các nhà phát triển có kinh nghiệm đôi khi cũng cần tra cứu cách sử dụng các lớp này!
Tiếp tục thử nghiệm với các ví dụ này, thử thay đổi chúng và xem会发生什么. Trước khi bạn biết, bạn sẽ có thể xử lý ngày và giờ như một true Java time traveler!
Chúc bạn may mắn và thời gian của bạn luôn chính xác! ⏰?
Credits: Image by storyset