SimpleDateFormat và DateFormat trong Java
Các lớp SimpleDateFormat và DateFormat của Java là rất quan trọng để xử lý định dạng ngày và giờ trong các ứng dụng Java. Các lớp này thuộc gói java.text và cung cấp một framework mạnh mẽ để chuyển đổi ngày thành chuỗi và ngược lại, dựa trên các locale cụ thể.
SimpleDateFormat cho phép bạn xác định các mẫu (pattern) để định dạng ngày và giờ, làm cho nó có khả năng tùy chỉnh cao. Ví dụ, bạn có thể chỉ định các mẫu như “dd-MM-yyyy” cho ngày hoặc “HH:mm:ss” cho giờ. Sự linh hoạt này rất quan trọng đối với các ứng dụng cần hiển thị ngày và giờ theo nhiều định dạng khác nhau tùy thuộc vào sở thích của người dùng hoặc cài đặt khu vực.
Mặt khác, DateFormat cung cấp một cách tiếp cận đơn giản hơn để định dạng ngày và giờ bằng cách sử dụng các kiểu được xác định trước như SHORT, MEDIUM, LONG, và FULL. Nó cũng hỗ trợ localization, đảm bảo rằng ngày và giờ được định dạng theo quy ước của các khu vực và ngôn ngữ khác nhau.
Tuy nhiên, điều quan trọng cần lưu ý là cả SimpleDateFormat và DateFormat đều không an toàn cho luồng. Điều này có nghĩa là nếu bạn đang sử dụng các lớp này trong môi trường đa luồng (multi-threaded), bạn nên tạo các instance (thể hiện) riêng biệt cho mỗi luồng để tránh các vấn đề về đồng thời. Gần đây, Java đã giới thiệu gói java.time trong Java 8, cung cấp một cách tiếp cận hiện đại và toàn diện hơn để xử lý ngày và giờ. Gói này bao gồm các lớp như LocalDate, LocalTime, LocalDateTime, và DateTimeFormatter, mang lại hiệu suất tốt hơn và an toàn cho luồng. Mặc dù vậy, SimpleDateFormat và DateFormat vẫn được sử dụng rộng rãi, đặc biệt trong các ứng dụng cũ, do đó, việc hiểu cách sử dụng và khả năng của chúng là rất cần thiết.
Java DateFormat
- Lớp
DateFormatđược sử dụng để định dạng ngày thành chuỗi theo locale đã được chỉ định. Điều này rất quan trọng đối với các ứng dụng cần trình bày thông tin ngày và giờ theo cách quen thuộc với người dùng từ các khu vực khác nhau. - Các Locale được sử dụng để xác định khu vực và ngôn ngữ, đảm bảo rằng các định dạng ngày phù hợp với văn hóa. Ví dụ, ngày
31st Dec 2017được định dạng là31-12-2017ở Ấn Độ, trong khi ở Hoa Kỳ, nó xuất hiện dưới dạng12-31-2017. - Điều quan trọng cần lưu ý là các instance của
DateFormatkhông an toàn cho luồng. Do đó, nên tạo các instance riêng biệt cho mỗi thread (luồng) để tránh các vấn đề về đồng thời.
Bạn có thể tạo một đối tượng DateFormat bằng cách sử dụng các phương thức getDateInstance() và getTimeInstance(), cho phép định dạng ngày và giờ linh hoạt dựa trên locale mong muốn.
Locale loc = new Locale("en", "US");
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, loc);
Lưu ý: Phương thức constructor Locale(String, String) đã không còn được sử dụng từ phiên bản 19.
Locale loc = new Locale.Builder().setLanguage("en").setRegion("US").build();
Phương thức getDateInstance của DateFormat cần hai tham số đầu vào. Tham số đầu tiên chỉ định DateFormat sẽ được sử dụng và tham số thứ hai là locale.
Sử dụng format
Lớp DateFormat có một phương thức format chịu trách nhiệm định dạng.
Locale locale = new Locale("fr", "FR");
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
String date = dateFormat.format(new Date());
System.out.print(date);
Đoạn code này sẽ định dạng ngày bằng ngôn ngữ tiếng Pháp (fr) và khu vực Pháp (FR):
Output
3 janv. 2018
Sử dụng getTimeInstance()
Để tạo một DateFormat instance, chúng ta sử dụng phương thức getDateInstance().
Để thực hiện định dạng thời gian, chúng ta cần một instance của thời gian. Chúng ta sẽ sử dụng phương thức getTimeInstance() để lấy một instance của thời gian.
Locale locale = new Locale("fr", "FR");
DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
String date = dateFormat.format(new Date());
System.out.print(date);
Đoạn code này sẽ định dạng thời gian bằng ngôn ngữ tiếng Pháp (fr) và khu vực Pháp (FR):
Output
11:03:01
Java SimpleDateFormat
SimpleDateFormat tương tự như DateFormat. Sự khác biệt lớn duy nhất giữa chúng là SimpleDateFormat có thể được sử dụng để định dạng (Date sang String) và để parsing (phân tích chuỗi, String sang Date) với hỗ trợ locale, trong khi DateFormat không có hỗ trợ locale. DateFormat là một lớp abstract class cung cấp hỗ trợ cơ bản cho định dạng và parsing ngày. SimpleDateFormat là một lớp concrete class mở rộng lớp DateFormat.
SimpleDateFormat có thể được tạo bằng cách sử dụng SimpleDateFormat constructor. Constructor là một constructor có tham số và cần một mẫu String làm tham số.
String pattern = "MM-dd-yyyy";
SimpleDateFormat simpleDateFormat = newSimpleDateFormat(pattern);
Mẫu String là mẫu sẽ được sử dụng để định dạng ngày và đầu ra sẽ được tạo theo mẫu đó, ví dụ “MM-dd-yyyy”.
Mẫu
Hãy xem xét cú pháp mẫu (pattern syntax) nên được sử dụng cho mẫu định dạng.
| Ký tự mẫu | Thành phần ngày/giờ | Ví dụ |
|---|---|---|
| G | Ký hiệu thời đại | AD |
| y | Năm | 2018 (yyyy), 18 (yy) |
| M | Tháng trong năm | July (MMMM), Jul (MMM), 07 (MM) |
| w | Tuần trong năm | 16 |
| W | Tuần trong tháng | 3 |
| D | Số thứ tự ngày trong năm | 266 |
| d | Ngày trong tháng | 09 (dd), 9 (d) |
| F | Thứ tự ngày trong tuần của tháng | 4 |
| E | Tên ngày trong tuần | Tuesday, Tue |
| u | Số thứ tự ngày trong tuần (1 = Thứ Hai, 2 = Thứ Ba, …) | 2 |
| a | Ký hiệu AM/PM | AM |
| H | Giờ trong ngày (0–23) | 12 |
| k | Giờ trong ngày (1–24) | 23 |
| K | Giờ trong buổi (0–11, định dạng 12h) | 0 |
| h | Giờ trong buổi (1–12, định dạng 12h) | 12 |
| m | Phút trong giờ | 59 |
| s | Giây trong phút | 35 |
| S | Mili-giây trong phút | 978 |
| z | Múi giờ | Pacific Standard Time; PST; GMT-08:00 |
| Z | Độ lệch múi giờ theo giờ (theo chuẩn RFC) | -800 |
| X | Độ lệch múi giờ theo chuẩn ISO | -08; -0800; -08:00 |
Một số ký tự nên được sử dụng với số lượng khác nhau cho các kết quả khác nhau, ví dụ cho tháng:
| Loại | Mẫu | Ví dụ kết quả |
|---|---|---|
| Tháng đầy đủ | MMMM | July |
| Tháng viết tắt | MMM | Jul |
| Tháng dạng số | MM | 7 |
Ví dụ
Bây giờ chúng ta hãy xem một số ví dụ cho các định dạng ngày và giờ khác nhau.
| Mẫu (Pattern) | Kết quả (Result) |
|---|---|
| MM/dd/yyyy | 01/02/2018 |
| dd-M-yyyy hh:mm:ss | 02-01-2018 6:07:59 |
| dd MMMM yyyy | 02 January 2018 |
| dd MMMM yyyy zzzz | 02 January 2018 India Standard Time |
| E, dd MMM yyyy HH:mm:ss z | Tue, 02 Jan 2018 18:07:59 IST |
Sử dụng SimpleDateFormat()
Để phân tích một ngày, chúng ta cần tạo một instance của SimpleDateFormat bằng cách sử dụng constructor và sau đó sử dụng phương thức format():
String pattern = "MM-dd-yyyy";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
String date = simpleDateFormat.format(new Date());
System.out.println(date);
Đoạn code này sẽ xuất ra “MM-dd-yyyy”:
Output
01-02-2018
Mẫu này tạo ra “tháng trong năm”, “ngày trong tháng” và “năm”. Kiểu ký tự (và viết hoa/viết thường) và số lượng ký tự đóng góp vào chuỗi. Tháng sẽ được biểu diễn dưới dạng hai chữ số, ngày dưới dạng hai chữ số và năm dưới dạng bốn chữ số.
Đoạn code này hiển thị ngày “January 2, 2018” là “01-02-2018”.
Để phân tích thời gian, chúng ta phải thay đổi mẫu trong khi tạo SimpleDateFormat instance.
String pattern = "HH:mm:ss.SSSZ";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
String date = simpleDateFormat.format(new Date());
System.out.println(date);
Đoạn code này sẽ xuất ra “HH:mm:ss.SSSZ”:
Output
13:03:15.454+0530
Mẫu này tạo ra “giờ”, “phút”, “giây”, “mili giây” và “timezone offset (múi giờ chênh lệch) theo giờ (mẫu RFC)”.
Đoạn code này hiển thị thời gian là “13:03:15.454+0530”.
Sử dụng parse()
Parsing là quá trình chuyển đổi String thành một java.util.Date instance. Chúng ta có thể parse một chuỗi thành một ngày bằng cách sử dụng phương thức parse() của lớp SimpleDateFormat. Để parse một String sang Date, chúng ta cần một instance của lớp SimpleDateFormat và một mẫu chuỗi làm đầu vào cho constructor của lớp.
String pattern = "MM-dd-yyyy";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Date date = simpleDateFormat.parse("12-01-2018");
System.out.println(date);
Đoạn code này sẽ xuất ra một ngày (12-01-2018) mà không có thời gian cụ thể:
Output
Sat Dec 01 00:00:00 IST 2018
Bây giờ hãy xem ví dụ SimpleDateFormat để parse thời gian.
String pattern = "HH:mm:ss";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Date date = simpleDateFormat.parse("22:00:03");
System.out.println(date);
Đoạn code này sẽ xuất ra một thời gian (22:00:03) mà không có ngày cụ thể:
Output
Thu Jan 01 22:00:03 IST 1970
Bởi vì chúng ta chưa chỉ định bất kỳ ngày nào, chương trình đã coi ngày epoch là ngày (01-Jan-1970).
Sử dụng Locale
Chúng ta đã làm việc với Locale như một phần của DateFormat và chúng ta đã thấy rằng các locale được sử dụng dựa trên các khu vực.
String pattern = "EEEEE MMMMM yyyy HH:mm:ss.SSSZ";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, new Locale("fr", "FR"));
Date date = simpleDateFormat.format(new Date());
System.out.println(date);
Đoạn code này sẽ định dạng thời gian hiện tại bằng ngôn ngữ tiếng Pháp (fr) và khu vực Pháp (FR):
Output
mardi janvier 2018 14:51:02.354+0530
Ngày và tháng được đặt tên bằng tiếng Pháp dựa trên Locale được cung cấp làm đầu vào – mardi là “Tuesday” và janvier là “January”.
Kết luận
Trong bài viết này, bạn đã tìm hiểu về SimpleDateFormat và DateFormat của Java. Để xử lý ngày và giờ nâng cao hơn trong Java, hãy cân nhắc sử dụng gói java.time được giới thiệu trong Java 8, bao gồm LocalDate, LocalDateTime, và Instant. Các lớp này cung cấp một cách tiếp cận toàn diện và linh hoạt hơn để thao tác với ngày và giờ.
Để hiểu sâu hơn về các lớp mới này, bạn có thể tham khảo Java 8 Date, LocalDate, LocalDateTime, Instant tutorial, giải thích cách làm việc với API ngày-giờ hiện đại trong Java.
Tài liệu tham khảo:
Câu hỏi thường gặp (FAQs)
Định dạng ngày trong Java SimpleDateFormat là gì?
Lớp SimpleDateFormat trong Java cho phép bạn định dạng và parse ngày theo một mẫu cụ thể. Các mẫu phổ biến bao gồm:
yyyy: Năm 4 chữ số (ví dụ: 2024)MM: Tháng 2 chữ số (ví dụ: 01 cho tháng 1)dd: Ngày trong tháng 2 chữ số (ví dụ: 09)HH: Giờ ở định dạng 24 giờ (ví dụ: 14 cho 2 PM)mm: Phút 2 chữ sốss: Giây 2 chữ số
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = sdf.format(new Date());
Làm thế nào để chuyển đổi SimpleDateFormat thành một ngày trong Java?
Để chuyển đổi một chuỗi SimpleDateFormat thành một đối tượng Date, sử dụng phương thức parse():
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateString = "2024-12-19";
Date date = sdf.parse(dateString);
Làm thế nào để tạo một ngày ở định dạng yyyy-MM-dd trong Java?
Để tạo một ngày ở định dạng yyyy-MM-dd:
- Sử dụng lớp
SimpleDateFormatđể định dạng một đối tượng Date.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = sdf.format(new Date());
System.out.println(formattedDate); // Output: 2024-12-19
Định dạng ngày đơn giản cho DD MM YYYY trong Java là gì?
Định dạng cho DD MM YYYY trong Java là “dd MM yyyy”. Đây là cách sử dụng nó:
SimpleDateFormat sdf = new SimpleDateFormat("dd MM yyyy");
String formattedDate = sdf.format(new Date());
System.out.println(formattedDate); // Output: 19 12 2024
Làm thế nào để chuyển đổi định dạng ngày từ MM DD YYYY sang DD MM YYYY trong Java?
Để chuyển đổi một ngày từ MM DD YYYY sang DD MM YYYY, bạn cần parse định dạng ban đầu và định dạng lại nó thành định dạng mong muốn:
SimpleDateFormat inputFormat = new SimpleDateFormat("MM dd yyyy");
SimpleDateFormat outputFormat = new SimpleDateFormat("dd MM yyyy");
String dateString = "12 19 2024";
Date date = inputFormat.parse(dateString);
String reformattedDate = outputFormat.format(date);
System.out.println(reformattedDate); // Output: 19 12 2024
Làm thế nào để lấy ngày hiện tại trong Java ở định dạng MM DD YYYY?
Để lấy ngày hiện tại ở định dạng MM DD YYYY, sử dụng lớp SimpleDateFormat:
SimpleDateFormat sdf = new SimpleDateFormat("MM dd yyyy");
String currentDate = sdf.format(new Date());
System.out.println(currentDate); // Output: 12 19 2024
