Jon Skeet’s answer là chính xác và là một câu trả lời tốt khi nó được viết vào năm 2013.
Tuy nhiên, các lớp bạn sử dụng trong câu hỏi của bạn, SimpleDateFormat
và Date
, bây giờ là lỗi thời gian dài, vì vậy nếu một người nào đó có một vấn đề tương tự với chúng ngày hôm nay, IMHO câu trả lời tốt nhất sẽ là thay đổi để sử dụng the modern Java date & time API.
Tôi xin lỗi tôi không thể viết mã Scala, vì vậy bạn sẽ phải sống với Java. Tôi đang sử dụng
private static DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy");
Ký tự mẫu định dạng giống như câu hỏi của bạn, mặc dù ý nghĩa hơi khác. DateTimeFormatter
nhận số chữ hoa văn theo nghĩa đen, như chúng ta sẽ thấy. Bây giờ chúng ta thử:
System.out.println(LocalDate.parse(date, parseFormatter));
Kết quả:
"03/11/2013"
được phân tách thành 2013-03-11
như mong đợi. Tôi đã sử dụng lớp LocalDate
hiện đại, một lớp đại diện cho một ngày không có thời gian trong ngày, chính xác những gì chúng tôi cần ở đây.
- Chuyển
"03/88/2013 hjhkjhk"
cho số DateTimeParseException
với thông báo Text '03/88/2013 hjhkjhk' could not be parsed, unparsed text found at index 10
. Khá chính xác, phải không?API hiện đại có phương pháp phân tích cú pháp chỉ một phần của chuỗi nếu đó là những gì chúng tôi muốn.
"03/88/201309"
cho Text '03/88/201309' could not be parsed at index 6
. Chúng tôi đã yêu cầu một năm có 4 chữ số và cho nó 6 chữ số, dẫn đến phản đối. Dường như nó phát hiện và báo cáo lỗi này trước khi cố gắng diễn dịch 88 như một ngày trong tháng.
- Nó cũng phản đối một ngày trong tháng là 88, mặc dù:
"03/88/2013"
cung cấp Text '03/88/2013' could not be parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 88
. Một lần nữa, hãy tận hưởng thông điệp như thế nào.
"03-08-2013"
(có dấu gạch ngang thay vì dấu gạch chéo) cho số Text '03-08-2013' could not be parsed at index 2
, không quá ngạc nhiên. Chỉ số 2 là nơi dấu gạch nối đầu tiên là.
Jon Skeet giải thích rằng lỗi thời SimpleDateFormat
có thể được khoan dung hoặc không khoan dung. Điều này cũng đúng với cả DateTimeFormatter
, trên thực tế nó có 3 thay vì 2 kiểu phân giải, được gọi là ‘khoan dung’, ‘thông minh’ và ‘nghiêm ngặt’. Vì nhiều lập trình viên không nhận thức được điều này, mặc dù, tôi nghĩ rằng họ đã thực hiện một lựa chọn tốt là không làm 'khoan dung' mặc định (‘thông minh’ là).
Điều gì xảy ra nếu chúng tôi muốn làm cho trình định dạng của chúng tôi trở nên khoan dung?
private static DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy")
.withResolverStyle(ResolverStyle.LENIENT);
Bây giờ, nó cũng phân tích cú pháp "03/88/2013"
, thành 2013-05-27
. Tôi tin rằng đây là những gì lớp học cũ cũng đã làm: đếm 88 ngày kể từ đầu tháng 3 cho đến ngày 27 tháng 5. Các thông báo lỗi khác vẫn như cũ. Nói cách khác, nó vẫn đối tượng với văn bản chưa được phân tích, đến năm có 6 chữ số và dấu gạch nối.
Câu hỏi: Tôi có thể sử dụng API hiện đại với phiên bản Java của mình không?
Nếu sử dụng ít nhất Java , bạn có thể.
- Trong Java 8 trở lên, API mới được tích hợp sẵn.
- Trong Java 6 và 7 nhận được the ThreeTen Backport, cổng sau của các lớp mới (đó là ThreeTen cho JSR-310, nơi API hiện đại được xác định lần đầu).
- Trên Android, sử dụng phiên bản Android của ThreeTen Backport. Nó được gọi là ThreeTenABP và tôi nghĩ rằng có một lời giải thích tuyệt vời trong số this question: How to use ThreeTenABP in Android Project.
'var date'? Tôi không nghĩ như vậy, sao chép mã thực sự của bạn vào câu hỏi xin vui lòng. – Perception
'var date' không phải là Java. –
@Lutz Horn. Tôi đang sử dụng scala – Rishi