2013-01-02 57 views
16

Tôi nhận được hai ngày làm giá trị Chuỗi và tôi muốn kiểm tra thời gian bắt đầu sớm hơn thời gian kết thúc. Tôi so sánh chúng vì nó là không có chuyển đổi chúng sang ngày sử dụng SimpleDateFormat, như thế này:so sánh ngày ở định dạng Chuỗi

String startTime = "2013-01-02 14:25:56"; 
String endTime = "2013-01-02 14:30:56"; 

if(endTime.compareTo(startTime) > 0){ 
    System.out.println("End time is greater than start time"); 
} 

Là nó thực sự cần thiết để chuyển đổi chúng cho đến nay và so sánh? Tôi sẽ bỏ lỡ bất cứ điều gì? Tôi có làm đúng không?

+7

định dạng yyyy-mm-dd là tốt vì nếu bạn sắp xếp các loại giá trị này, bạn sẽ nhận được các giá trị chính xác, nếu bạn có mm.dd.yyyy hoặc dd.mm.yyyy, bạn sẽ nhận được kết quả sai ... tại một cái nhìn đầu tiên, tất cả đều ok –

+2

Nếu bạn chắc chắn sẽ luôn có cùng định dạng này, thì bạn an toàn ... –

+4

Đáng chú ý là tại sao nó hoạt động theo cách bạn có các chuỗi: [phân loại theo từ điển] (http://en.wikipedia.org/wiki/Lexicographical_order) –

Trả lời

9

Có thực sự cần thiết để chuyển đổi chúng cho đến nay và so sánh không?

Nếu bạn không phải bao gồm múi giờ và có thể đảm bảo rằng bạn luôn có định dạng này, thứ tự từ vựng sẽ hoạt động.

Tôi có bỏ lỡ bất cứ điều gì không?

Bạn mất sự linh hoạt

Tôi có làm điều đúng đắn?

Điều đó tùy thuộc vào quan điểm. Tôi sử dụng một cái gì đó tương tự trong một enginge tìm kiếm chuyên ngành (chỉ vì lý do hiệu suất). Thông thường tôi chuyển đổi thành Date và so sánh các đối tượng này.

17

Điều bạn sẽ thiếu là xác minh nếu ngày thực tế được định dạng đúng.

Nếu các ngày được định dạng chính xác như bạn đã hiển thị mọi lúc, thì thao tác này sẽ hoạt động. Nếu có bất kỳ cơ hội nào có thể khác, thì phân tích cú pháp và so sánh các đối tượng Date kết quả sẽ thêm ít nhất một phần của séc.

Ví dụ nếu một trong hai ngày xảy ra được định dạng là 2013.01.02 14:30:56 hoặc thậm chí nó bao gồm một ngày không định dạng như yesterday sau đó mã của bạn sẽ âm thầm thừa nhận một số thứ tự (mà hầu như có rất ít để làm với thứ tự thực tế) và tiếp tục. Những gì nó nên làm là thông báo cho người dùng (hoặc tệp nhật ký, ...) rằng một số kỳ vọng không được đáp ứng.

+3

Điểm tốt. Một sự khác biệt tinh tế hơn với so sánh chuỗi có thể là nếu bạn so sánh '2013-01-01 08: 42: 42' và' 2013-01-01 8: 42: 42' và mong đợi chúng bằng nhau. – Alderath

+1

@Alderath: vâng, đó là những gì tôi viết về khi tôi viết "được định dạng * chính xác * như bạn đã trình bày". Nếu có bất kỳ * biến thể nào trong định dạng, thì phân tích cú pháp là giải pháp thay thế an toàn hơn nhiều (và như tôi đã gợi ý: tôi sẽ phân tích cú pháp + so sánh trong mọi trường hợp, trừ khi có lý do * rất * không tốt). –

+0

Vâng. Lấy làm tiếc. Tôi không ngụ ý rằng tôi đã khám phá ra bất cứ điều gì mà bạn không biết. Tôi chỉ đưa ra một ví dụ khác về cách ngày tháng có thể khác nhau. Điều đáng chú ý với sự khác biệt này là nếu người dùng được nhắc nhập liệu và "2013-01-02 14:25:56" đã được sử dụng làm ví dụ cho định dạng ngày cần có, thì không rõ có hay không có số 0 đứng đầu cần thiết cho giờ chỉ với một chữ số. (Nhưng tôi đoán rằng đầu vào mà OP đưa ra cho phương thức so sánh không phải là đầu vào của người dùng, bởi vì nếu nó là, nó chắc chắn sẽ cần phải được xác nhận) – Alderath

1

Tôi khuyên bạn nên chuyển đổi chúng thành ngày đầu tiên để an toàn hơn một chút, nhưng miễn là bạn CHẮC CHẮC định dạng (hoặc múi giờ, v.v ...) sẽ không bao giờ thay đổi, sau đó so sánh ngày và so sánh định dạng đó của chuỗi phải luôn luôn là tương đương.

1

cách tiếp cận của bạn là tốt vì yyyy-mm-dd hh: ii: ss có thể được so sánh như là một chuỗi và nhận được kết quả chính xác, định dạng ngày khác sẽ thất bại

tùy chọn khác là để đọc câu hỏi stackoverflow này

How to compare dates in Java?

và bạn chỉ nên phân tích chuỗi của bạn và tạo ra ngày hoặc Lịch đối tượng, phụ thuộc vào những gì bạn muốn làm, dưới đây là điều mà tôi thấy hữu ích

http://www.mkyong.com/java/java-how-to-get-current-date-time-date-and-calender/

1

Có, tốt hơn là chuyển đổi Chuỗi thành Ngày và so sánh.

  1. Đảm bảo rằng đây thực sự là ngày hợp lệ để không có ngày 20-20-2012.
  2. Sau khi chuyển đổi hoàn tất, chỉ còn một so sánh số duy nhất.
  3. Nó cho phép sự linh hoạt tuyệt vời khi so sánh ngày của các định dạng khác nhau.
  4. Cách thay thế là viết mã phân tích từng số và so sánh nó với số khác, điều này cũng giống như nhiều công việc.
2

gì về

"999-01-01 00:00:00" 

"10000-01-01 00:00:00" 
+0

ví dụ tốt nhưng điều này phá vỡ toàn bộ điểm giữ cùng một định dạng ngày, trong để so sánh đúng, chúng ta nên so sánh 10000 với 00999 và nhận được kết quả tốt, nếu không, nó sẽ thất bại –

7

Bạn có thể so sánh thời gian ngày mà không đúng cách phân tích nó khi và chỉ khi những 3 điều kiện được đáp ứng:

  1. Thời gian ngày luôn trong cùng một định dạng:

    • Cùng số trường
    • Các trường phải hoàn toàn là số. (So ​​sánh chuỗi: Jan>April, Wed>Thu).
    • Kích thước của các trường được cố định (0 đệm nếu cần). Ví dụ: không có đệm thích hợp sẽ dẫn đến 10:01 < 1:01 (: có mã ASCII lớn hơn chữ số).
    • Các phần không phải là số (bao gồm cả dấu tách) phải giống nhau về khoảng cách.
  2. Các trường được sắp xếp theo thứ tự giảm dần theo kích thước của đơn vị (đơn vị lớn hơn bên phải và đơn vị nhỏ hơn ở bên trái). Ví dụ: YEAR-MONTH-DAY HOUR:MINUTE:SECOND.MILISECOND

  3. Chúng phải nằm trong cùng múi giờ. Thông tin múi giờ, nếu có, phải có cùng một bản trình bày (SGTUTC+8 hiện tương đương, nhưng so sánh Chuỗi sẽ không biết về điều này). Lưu ý rằng ở trên mơ hồ trạng "cùng múi giờ" là đủ để so sánh bằng nhau, nhưng để so sánh lớn hơn/nhỏ hơn, có phải không có thay đổi trong múi giờ xảy ra giữa 2 ngày được so sánh.

+0

+1 cho độ chính xác. Tôi nghĩ bạn có thể nói iif. – assylias

+0

+1 để đề cập đến múi giờ. làm thế nào tôi ghét họ. – f1sh

8

Thực tiễn không tốt và mùi mã.

Bạn mất mã ngữ nghĩa chính xác và có thể đọc được. (Và khả năng mở rộng, múi giờ, và những điều khác ngay, mà đã đã nói)

Bạn không muốn so sánh hai String s, bạn muốn so sánh 2 Date s - vì vậy chỉ cần làm điều này, so sánh hai đối tượng Date .

Nếu bạn tạo đơn vị kiểm tra và kiểm tra phương pháp so sánh của mình, bạn sẽ không bao giờ viết phương thức so sánh 2 "chuỗi" một cách chính xác trong mọi trường hợp, mà không chuyển đổi chúng thành ngày.

+1

Tôi phải đồng ý với câu trả lời này nhất. Để so sánh như là chuỗi là một cách tiếp cận mong manh cho phần mềm. Có, bạn có thể cẩn thận xác định các điều kiện trong đó nó hoạt động, nhưng nó có khả năng thất bại tại một số điểm trong tương lai, theo một cách rất khó tìm. Bạn chỉ đơn giản là không thể đảm bảo những gì sẽ hoặc sẽ không thay đổi trong tương lai. – dashrb

+1

+1 để sử dụng ngữ nghĩa mã. quá thường xuyên, chúng tôi nghe nói rằng "nó hoạt động, vì vậy nó ok", nhưng nếu mã theo ngữ nghĩa, bạn sẽ không nhận được mình trong một cái bẫy dễ dàng như vậy. – Javier

0

Ngày của tôi đến từ nguồn dựa trên chuỗi và luôn được định dạng YYYY-MM-DD, không có thông tin múi giờ hoặc các biến chứng khác. Vì vậy, khi so sánh một danh sách dài các ngày, nó đơn giản và hiệu quả hơn để so sánh chúng dưới dạng chuỗi thay vì chuyển đổi chúng thành các đối tượng ngày đầu tiên.

này chưa bao giờ là một vấn đề cho đến khi tôi làm sai lầm này trong mã của tôi:

boolean past = (dateStart.compareTo(now) == -1); 

này được đưa ra một số kết quả không chính xác vì compareTo không chỉ trả về giá trị là -1, 0 hoặc 1. Đây là sửa lỗi đơn giản:

boolean past = (dateStart.compareTo(now) < 0); 

Tôi bao gồm hình ảnh này ở đây vì đây là một trong những câu hỏi SO tôi tìm thấy khi cố gắng tìm ra những gì tôi đã làm sai.