Tổng Quan Ngày & Giờ (Date & Time)

Java cung cấp nhiều lớp và thư viện để làm việc với dữ liệu về ngày và thời gian. Việc xử lý ngày tháng trong lập trình là rất phổ biến, từ việc lưu trữ thông tin người dùng đến tính toán các khoảng thời gian. Các lớp này được chia thành các lớp cũ từ Java 1.0 (trong java.util package) và các lớp mới từ Java 8 (trong java.time package).

Ⅰ. API ngày giờ thời kỳ đầu (Classical Date/Time API)

Mặc dù API Ngày Giờ Mới (Java 8 Date/Time API) được khuyến khích sử dụng hiện nay, API Ngày Giờ Thời Kỳ Đầu (Classical Date/Time API) đôi khi vẫn hữu ích. Dưới đây là danh sách các lớp ngày giờ thời kỳ đầu trong Java:

↳ Lớp java.util.Date: Lớp này biểu diễn thời điểm tức thời (một điểm cụ thể trong thời gian). Nó thường được dùng để lưu trữ mốc thời gian, chẳng hạn như ngày tạo ra một tập tin.

↳ Lớp java.sql.Date: Lớp này biểu diễn ngày theo định dạng YYYY-MM-DD, thường được sử dụng để tương tác với cơ sở dữ liệu quan hệ.

↳ Lớp java.util.Calendar: Lớp này linh hoạt hơn java.util.Date vì nó cung cấp các phương thức để truy xuất và thao tác với các phần riêng lẻ của ngày giờ (năm, tháng, ngày, giờ, phút, giây, v.v.). Tuy nhiên, lớp Calendar phức tạp hơn để sử dụng và dễ gây ra lỗi.

↳ Lớp java.util.GregorianCalendar: Lớp này là một triển khai cụ thể của Calendar theo lịch Gregorian, thường được sử dụng nhất.

↳ Lớp java.util.TimeZone: Lớp này biểu diễn múi giờ.

↳ Lớp java.sql.Time: Lớp này biểu diễn thời gian trong ngày theo định dạng HH:MM:SS, thường được sử dụng để tương tác với cơ sở dữ liệu quan hệ. giờ.

↳ Lớp java.sql.Timestamp: Lớp này kết hợp ngày và giờ với độ chính xác đến mili giây, thường được sử dụng để lưu trữ các mốc thời gian trong cơ sở dữ liệu quan hệ.

Hạn chế của API ngày giờ thời kỳ đầu

↳ Không an toàn cho nhiều luồng (Thread safety): Các lớp cũ như Date và Calendar không an toàn cho nhiều luồng. Điều này dẫn đến các vấn đề về đồng thời khó gỡ rối (concurrency issues) mà developer cần phải xử lý. API Ngày Giờ mới trong Java 8 cung cấp tính an toàn cho nhiều luồng và không thay đổi giá trị (immutable), do đó tránh được các vấn đề về đồng thời cho developer.

↳ Thiết kế API không tốt: API Ngày Giờ cũ (Date và Calendar) không cung cấp các phương thức để thực hiện các chức năng cơ bản hàng ngày. Các lớp Ngày Giờ được giới thiệu trong Java 8 theo chuẩn ISO và cung cấp nhiều phương thức khác nhau để thực hiện các phép toán liên quan đến ngày, giờ, khoảng thời gian và các giai đoạn.

↳ Xử lý múi giờ khó khăn: Xử lý múi giờ bằng các lớp Date và Calendar cũ rất khó khăn vì developer cần phải viết logic cho nó. Với API mới, việc xử lý múi giờ có thể dễ dàng thực hiện với các API Local và ZonedDate/Time.

Ⅱ. API ngày giờ Java 8 (Java 8 Date/Time API)

Kể từ Java 8, Java đã giới thiệu một API Ngày Giờ (Date/Time) hoàn toàn mới giúp khắc phục những hạn chế của các lớp cũ được đề cập ở trên. Nó bao gồm các lớp sau:

Các lớp ngày giờ của Java 8 nằm trong gói java.time.

Các lớp biểu diễn ngày, giờ, ngày giờ:

↳ java.time.LocalDate: Biểu diễn ngày theo định dạng YYYY-MM-DD.

↳ java.time.LocalTime: Biểu diễn thời gian trong ngày theo định dạng HH:MM:SS.

↳ java.time.LocalDateTime: Kết hợp cả ngày (LocalDate) và giờ (LocalTime).

Các lớp biểu diễn các khoảng thời gian đặc biệt:

↳ java.time.MonthDay: Biểu diễn ngày trong tháng (ví dụ: ngày 13 tháng 8).

Các lớp biểu diễn thời gian với múi giờ:

↳ java.time.OffsetTime: Biểu diễn thời gian theo định dạng HH:MM:SS kèm theo sự lệch chuẩn với Giờ Phối hợp Quốc tế (UTC).

↳ java.time.OffsetDateTime: Kết hợp cả ngày giờ (LocalDateTime) và sự lệch chuẩn với UTC (OffsetTime).

↳ java.time.ZonedDateTime: Biểu diễn thời gian theo định dạng YYYY-MM-DD HH:MM:SS kèm theo múi giờ cụ thể.

Các lớp liên quan đến múi giờ:

↳ java.time.Clock: Lấy thời gian hiện tại theo múi giờ hệ thống hoặc múi giờ tùy chỉnh.

↳ java.time.ZoneId: Biểu diễn một múi giờ cụ thể (ví dụ: giờ Việt Nam Asia/Ho_Chi_Minh).

↳ java.time.ZoneOffset: Biểu diễn sự lệch chuẩn giữa múi giờ nào đó với Giờ Phối hợp Quốc tế (UTC).

Các lớp biểu diễn các khoảng thời gian:

↳ java.time.Year: Biểu diễn năm.

↳ java.time.YearMonth: Biểu diễn tháng trong năm (ví dụ: tháng 10 năm 2024).

↳ java.time.Period: Biểu diễn một khoảng thời gian giữa hai ngày, bao gồm các trường năm, tháng, ngày.

↳ java.time.Duration: Biểu diễn một khoảng thời gian tính bằng nano giây, mili giây, giây, phút, giờ, v.v.

Các lớp khác:

↳ java.time.Instant: Biểu diễn một thời điểm tức thời tính bằng mili giây kể từ 1970-01-01T00:00:00Z (Giờ Coordinated Universal Time).

Các kiểu liệt kê (enum):

↳ java.time.DayOfWeek: Biểu diễn các ngày trong tuần (thứ Hai, thứ Ba, ...).

↳ java.time.Month: Biểu diễn các tháng trong năm (tháng 1, tháng 2, ...).

Phân loại API làm việc với ngày giờ trong Java - minh họa
Ảnh mô tả Phân loại API để làm việc với ngày giờ trong java.

Ⅲ. Định dạng ngày giờ trong Java

Định dạng ngày giờ là quá trình chuyển đổi một đối tượng đại diện cho ngày và thời gian thành một chuỗi ký tự theo một mẫu nhất định. Java cung cấp các tính năng về ngày giờ thông qua hai gói: java.time (mới) và java.util (cũ). Gói java.time được giới thiệu trong Java 8 và các lớp được bổ sung nhằm khắc phục những hạn chế của các lớp cũ java.util.Date và java.util.Calendar.

Trong Java, chúng ta có thể định dạng ngày giờ bằng các lớp sau:

↳ Lớp java.text.DateFormat (đã cũ): Lớp trừu tượng này cung cấp các phương thức để định dạng và phân tích cú pháp ngày giờ theo một định dạng được cài đặt sẵn hoặc chỉ định bởi người dùng.

↳ Lớp java.text.SimpleDateFormat (đã cũ): Lớp này là một triển khai cụ thể của DateFormat. Nó được sử dụng để định dạng ngày giờ theo mẫu do người dùng cung cấp.

↳ Lớp java.time.format.DateTimeFormatter (khuyến khích sử dụng): Lớp này được sử dụng để định dạng và phân tích các đối tượng ngày giờ thuộc gói java.time.

Các mẫu định dạng phổ biến

↳ dd: Ngày, dạng số (01 - 31)

↳ MM: Tháng, dạng số (01 - 12)

↳ yyyy: Năm đầy đủ (ví dụ: 2024)

↳ HH: Giờ theo định dạng 24 giờ (00 - 23)

↳ hh: Giờ theo định dạng 12 giờ (01 - 12)

↳ mm: Phút (00 - 59)

↳ ss: Giây (00 - 59)

↳ a: Buổi sáng/chiều (AM/PM)

↳ Z: Múi giờ, ví dụ: +0700 (GMT+7)

Các ký tự đặc biệt:

↳ ': Sử dụng để bao bọc các ký tự văn bản

↳ [: Bắt đầu một bộ các ký tự

↳ ]: Kết thúc một bộ các ký tự

Ví dụ các mẫu định dạng khác:

↳ yyyy-MM-dd'T'HH:mm:ssXXX: Định dạng thời gian tiêu chuẩn ISO 8601. Ví dụ: 2023-01-01T15:30:00+07:00

↳ EEEE, dd MMMM yyyy: Hiển thị ngày đầy đủ với tên ngày trong tuần, ngày, tháng (bằng chữ) và năm. Ví dụ: Thứ Hai, 01 Tháng Một 2023

"Trong các chương tiếp theo, chúng ta sẽ khám phá sâu hơn về bộ thư viện java.time, một trong những cải tiến đáng kể của Java 8. Bạn sẽ được làm quen với các lớp đại diện cho giờ, ngày, múi giờ và tìm hiểu cách định dạng chúng một cách linh hoạt và chính xác."

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.”