2010-12-27 31 views
21

Nhận thức rõ ràng về các vấn đề về hiệu năng và luồng với SimpleDateFormat, tôi quyết định đi với FastDateFormat, cho đến khi tôi nhận ra rằng FastDateFormat chỉ dành cho định dạng, không phân tích cú pháp!Lựa chọn thay thế cho FastDateFormat để phân tích cú pháp ngày hiệu quả?

Có cách nào khác thay thế cho FastDateFormat, đã sẵn sàng để sử dụng ra khỏi hộp và nhanh hơn nhiều so với SimpleDateFormat?

Tôi tin rằng FastDateFormat là một trong những ứng dụng nhanh hơn, vì vậy mọi thứ nhanh như vậy sẽ làm.

Rất tò mò, bất kỳ ý tưởng nào tại sao FastDateFormat không hỗ trợ phân tích cú pháp? Nó không nghiêm trọng giới hạn việc sử dụng nó?

+4

Lưu ý: Kể từ lang 3.2, câu hỏi và câu trả lời này hiện đã lỗi thời. – Barett

Trả lời

18

Với dự đoán tốt nhất, hãy giữ FastDateFormat ... tốt ... nhanh, bằng cách giới hạn nó để chỉ hiển thị.

Apache Commons DateUtils có chức năng parseDate nhưng sử dụng SimpleDateFormat nội bộ.

Cách khác là sử dụng thư viện JodaTime. Đó là một sự thay thế hoàn toàn để xử lý các đối tượng DateFormat, DateCalendar.

JodaTime có DateTimeFormatter có thể được sử dụng để tạo các đối tượng DateTime (tương đương của JodaTime đối tượng Java Date) từ chuỗi.

Một ví dụ về làm thế nào để sử dụng nó là như thế này:

String strInputDateTime = "2010-12-27"; // An example, this would really come from outside 
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd"); 
DateTime dt = fmt.parseDateTime(strInputDateTime); 

Tôi không biết nếu điều này thực sự là nhanh hơn bất kỳ SimpleDateFormat, mặc dù.

+4

Lưu ý: Theo lang 3.2, câu hỏi và câu trả lời này hiện đã lỗi thời. – Barett

+0

Đó là sự khoan dung hay * không khoan dung *? –

1

Bạn có thực sự cần phải phân tích ngày nhanh chóng không? Bạn đã thử nghiệm SimpleDateFormat và thấy nó quá chậm cho nhu cầu của bạn?

Lưu ý, có nhiều cách để lưu vào bộ nhớ cache các thể hiện lớp chậm, không có chủ đề an toàn (ví dụ: ThreadLocal, pool).

+0

Tôi nhận ra rằng có một số kỹ thuật liên quan đến tổng hợp hoặc đa luồng, nhưng tôi đang tìm kiếm thứ gì đó trên giá. –

+0

còn câu hỏi khác của tôi thì sao? bạn đã xác nhận rằng SimpleDateFormat quá chậm cho nhu cầu của bạn chưa? – jtahlborn

+0

+1 cho ThreadLocal và "bạn có thực sự cần hiệu suất ở đây không". –

2

'Vấn đề' với SimpleDateFormat không phải là hiệu suất, độ an toàn của luồng.

Nếu bạn có hàng ngàn bài và đồng bộ hóa không phải là một sử dụng vấn đề đồng bộ (bạn cũng có thể gộp các trường hợp để giảm bớt này một chút)

Nếu bạn có một số tiền hợp lý của đề cách khuyến cáo là phải có một trường hợp riêng biệt cho mỗi SimpleDateFormat.

+0

Vì SimpleDateFormat không an toàn, bạn cần phải tạo một cá thể mới hoặc đồng bộ hóa quyền truy cập đồng thời vào một cá thể được chia sẻ. Nó cũng khá chậm. Đó là những gì tôi có nghĩa là do vấn đề hiệu suất. –

+0

Tùy thuộc vào tình huống của bạn, nhưng nếu bạn chỉ cần một (đó là lý do tại sao tôi giả sử bạn cần một phiên bản an toàn), bạn có thể tạo một phiên bản mới ở đầu mỗi luồng và sử dụng lại cùng một chuỗi trong chuỗi đó. Nếu bạn có hàng ngàn chủ đề được khởi tạo thì các chi phí của việc tạo một luồng cao hơn nhiều so với việc tạo ra cá thể đối tượng SimpleDateFormat thực tế. – jbx

+0

Đơn giản: Luôn sử dụng ThreadLocal với SimpleDateFormat. (http://download.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html) –

9

Tìm thấy một cái gì đó thú vị ở đây của trường hợp này trong Android: http://andmob.wikidot.com/faq-simpletimeformat

SimpleDateFormat, lần đầu tiên bạn thử phân tích cú pháp (hoặc, có lẽ, định dạng) một ngày, sẽ được tải trong tất cả các dữ liệu múi giờ cho ngôn ngữ của bạn. Quá trình này sẽ mất 2-3 giây. Đó là hy vọng rằng điều này sẽ được khắc phục trong một số ấn bản tương lai của Android.

Tạm thời, hãy cân nhắc sử dụng AsyncTask để "khởi động" SimpleDateFormat trong quy trình trước khi bạn cần. Chỉ cần phân tích cú pháp một số ngày trong AsyncTask doInBackground() để tải xuống múi giờ đôi khi nó sẽ không ảnh hưởng đến người dùng rất nhiều. Sau khi được khởi tạo trong quy trình của bạn, SimpleDateFormat sẽ chạy nhanh chóng cho đến khi quá trình của bạn bị ngắt .

+3

Đó là interessting, +1 cho điều đó! Nhưng vấn đề này là Android cụ thể và hơi tắt chủ đề, phải không? –

19

Lưu ý rằng vì commons-lang 3.2, FastDateFormat hỗ trợ phân tích cú pháp cũng như in.

Xem: http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/FastDateFormat.html

+0

ngạc nhiên bất ngờ, Apache cũng có FastDateParser để phân tích cú pháp – ahaaman

+1

Tôi đã phát hiện một cách đau đớn rằng việc phân tích cú pháp phân biệt chữ hoa chữ thường. (10Jan10 hoạt động. 10JAN10 không). Lỗi này được sửa trong 3.4 nhưng tại thời điểm nhận xét này, tôi không được thực hiện hoặc trong Maven. Nhìn về phía trước cho nó. https://issues.apache.org/jira/browse/LANG-996 – borjab

+0

Tôi có thể sai nhưng có vẻ như không có cách nào để đặt thuộc tính _lenient_ của FastDateParser thành ** false **. – ptha

5

Tính đến Java 8, người ta có thể sử dụng DateTimeFormatter cùng với các Java 8 Time API cho cả hai phân tích và định dạng ngày tháng. Từ tài liệu:

Lớp này không đổi và an toàn chỉ.

Bạn nên sử dụng lớp này nếu có thể cho công việc mới trong tương lai thay vì sử dụng SimpleDateFormat.

Các vấn đề liên quan