2009-09-23 34 views
16

Tôi muốn lưu một đối tượng Ngày vào một chuỗi có thể đọc được (ví dụ 22/10/2009 21:13:14) cũng có thể phân tích cú pháp trở lại đối tượng Ngày tháng.Định dạng ngày có thể đọc và phân tích cú pháp của con người trong Java

Tôi đã thử nhiều thứ và tốt nhất tôi có thể tìm thấy là sử dụng DateFormater để phân tích cú pháp và định hình nhưng nó có một trở ngại. Khi bạn định dạng ngày bạn mất thông tin giây. Tôi đã cố gắng để tìm nếu có một tùy chọn để định dạng nó và hiển thị các giây (thậm chí tốt hơn sẽ là mức mili giây kể từ đó là độ phân giải đối tượng Date cho phép bạn có) nhưng tôi đã đưa ra ngắn.

Bất kỳ ý tưởng nào?

Trả lời

37

Hãy xem java.text.SimpleDateFormat

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS"); 
Date dt = new Date(); 
String S = sdf.format(dt); // formats to 09/23/2009 13:53:28.238 
Date dt2 = sdf.parse(S); // parses back 
+0

Khi câu trả lời này đã được viết vào năm 2009 'SimpleDateFormat' là thứ chúng ta có cho mục đích này. Nó đã được chứng minh phiền hà và may mắn thay được thay thế bởi 'java.time', ngày Java hiện đại và API thời gian, và lớp' DateTimeFormatter' của nó vào năm 2014. Tôi khuyên bạn không bao giờ sử dụng 'SimpleDateFormat' nữa. –

4

SimpleDateFormat có thể định dạng và phân tích một ngày dựa trên một hệ thống mô hình rất đơn giản mà bao gồm thứ hai và thậm chí mili giây.

+1

@Unihedron Đã cập nhật liên kết. Người đánh giá, xin lưu ý rằng đây KHÔNG phải là câu trả lời chỉ có liên kết - câu trả lời vẫn có ý nghĩa mà không có liên kết và chính liên kết đó là tài liệu chính thức. –

2

Một chút ngoài chủ đề, nhưng tôi luôn cảm thấy cần phải nhắc mọi người rằng DateFormat và SimpleDateFormat không phải là chủ đề an toàn! Tài liệu của Sun nêu rõ điều này, nhưng tôi tiếp tục tìm mã trong tự nhiên, nơi mọi người gắn một SimpleDateFormat trong một ...

+0

Đó là lý do tại sao tất cả mọi người nên sử dụng Joda Time thay vào đó, và tự cứu mình đau đầu :) – Nick

+0

Tôi hoàn toàn đồng ý. Mặt khác, tôi muốn Sun sửa chữa những lớp này, vì vậy nếu không có gì khác, tôi không phải ngồi qua một "bài học đồng thời khác" - với những người cảnh báo tôi về chúng. (Oh mỉa mai ... Tôi chỉ làm chính xác điều tương tự ở đây trên StackOverflow :-)) –

4

Các câu trả lời khác đều tốt.

Nhưng khi thực hiện hình thức này mà xin chọn một định dạng mà loại đúng khi mã hóa như là một chuỗi .... "yyyy/MM/dd HH: mm: ss" là tốt. Nó luôn làm tôi kinh ngạc khi các kỹ sư phần mềm chọn một định dạng ngày mà không phân loại theo cách rõ ràng, thuận tiện.

Bạn sẽ tiết kiệm được các nhà phát triển đồng bào của bạn rất nhiều đau đớn tại một số điểm ở xa trong tương lai - nghĩ về nó như nghiệp tốt :-)

+0

"yyyy/dd/MM" không sắp xếp đúng. Xem xét rằng 2015/21/10, 2015/20/11 và 2015/22/11 được sắp xếp thành các chuỗi năm 2015/20/11, 2015/21/10, 2015/22/11. –

+2

Xin lỗi, ý tôi là yyyy/MM/dd. Đã sửa. – mikera

1

ISO 8601

Sử dụng định dạng ISO 8601.

  • Đó là linh hoạt, nó bao gồm giây và phần thứ hai nếu có bất kỳ, nhưng bạn cũng có thể để lại cho họ hiểu xem họ là 0.
  • Đó là tiêu chuẩn, vì vậy nhiều và các công cụ nhiều định dạng và phân tích nó. Tuyệt vời cho serialization cho lưu trữ hoặc trao đổi dữ liệu.
  • Nó giống như 2009-10-22T21:13:14, tôi nên nói nó khá dễ đọc (mặc dù số T ở giữa biểu thị phần bắt đầu của phần thời gian có thể cảm thấy bất thường lúc đầu).
  • Các chuỗi loại đúng cách, như mikera yêu cầu trong another answer, miễn là những năm nằm trong khoảng bốn chữ số từ 1000 đến 9999.
  • Các lớp của java.time, ngày Java hiện đại và thời gian API, cũng như của Joda Time phân tích cú pháp ISO 8601 làm mặc định của chúng, nghĩa là, không có bất kỳ định dạng rõ ràng nào và tạo ra cùng một định dạng từ các phương thức toString của chúng.

Một cuộc biểu tình khiêm tốn của việc sử dụng java.time:

LocalDateTime dateTime = LocalDateTime.of(2009, 10, 22, 21, 13, 14); 
String readableString = dateTime.toString(); 
System.out.println(readableString); 
LocalDateTime parsedBack = LocalDateTime.parse(readableString); 
System.out.println(parsedBack); 

này in hai dòng giống hệt nhau:

2009-10-22T21:13:14 
2009-10-22T21:13:14 

Sau System.out.println() gọi ngầm gọi toString() một lần nữa, vì vậy điều này không nên ngạc nhiên.

0

Nếu bạn muốn làm điều đó đơn giản hơn một chút, và được tha từ làm DateFormat của riêng bạn mà hầu hết các câu trả lời khác liên quan, bạn có thể tận dụng các định dạng mặc định trong java.time.Instant:

(new Date()).toInstant.toString(); 
Các vấn đề liên quan