2013-03-26 76 views
10

Xin chào Tôi có một đoạn mã như thế này:lỗi so sánh java.sql.Timestamp?

Date d1 = new java.sql.Timestamp(new Date().getTime()); 
Thread.sleep(10); 
Date d2 = new java.sql.Timestamp(new Date().getTime()); 
System.out.println("Date1: " + d1); 
System.out.println("Date2: " + d2); 
System.out.println("Comparing times d1.t < d2.t: " + (d1.getTime() < d2.getTime())); 
System.out.println("Comparing dates d1.before(d2): " + (d1.before(d2))); 

Kết quả trông như thế này:

Date1: 2013-03-26 11:04:01.093 
Date2: 2013-03-26 11:04:01.103 
Comparing times d1.t < d2.t: true 
Comparing dates d1.before(d2): false 

Có gì sai với lớp java.sql.Timestamp này?

Vâng, tôi đã thấy điều này:

Lưu ý: Đây là loại là một hỗn hợp của một java.util.Date và một giá trị nano giây riêng biệt. Chỉ những giây không thể tách rời được lưu trữ trong thành phần java.util.Date. Các giây phân số - các nanô - là riêng biệt. Phương thức Timestamp.equals (Object) không bao giờ trả về true khi truyền một giá trị kiểu java.util.Date vì thành phần nanos của một ngày không xác định. Kết quả là, phương thức Timestamp.equals (Object) không đối xứng đối với phương thức java.util.Date.equals (Object). Ngoài ra, phương thức hashcode sử dụng thực thi java.util.Date cơ bản và do đó không bao gồm các nanos trong tính toán của nó.

Do sự khác biệt giữa lớp Dấu thời gian và lớp java.util.Date được đề cập ở trên, nên mã không xem giá trị Dấu thời gian một cách tổng quát dưới dạng phiên bản java.util.Date. Mối quan hệ kế thừa giữa Timestamp và java.util.Date thực sự biểu thị thừa kế thực hiện, và không loại thừa kế.

Nhưng đối với ngày < -> Mối quan hệ dấu thời gian.

Trong ví dụ của tôi, tôi chỉ có Timestamps, và vẫn còn hành vi này là bất ngờ ..

UPDATE: ĐÁP

Lý do điều này xảy ra là phương pháp before() bị quá tải, không overriden trong java.sql.Timestamp. Tôi đã mong đợi một hành vi 'ghi đè'. Cách đúng để so sánh dấu thời gian là có biến Timestamp, không phải Ngày tháng.

này vẫn là một quyết định thiết kế nghèo trong lõi Java, vì thừa kế nên nghĩa Timestamp là-một ngày, không có hình phạt và ngoại lệ ..

+0

Tôi tin rằng tôi đã tìm thấy sự cố trong bài đăng khác. Vui lòng [xem lại] (http://stackoverflow.com/a/13141377/1758149). Vấn đề là bạn không phải coi một 'TimeStamp' là một ngày tháng. – RyPope

Trả lời

2

Hãy thử sử dụng Timestamp thay vì Date và nó sẽ hoạt động.

Timestamp d1 = new java.sql.Timestamp(new Date().getTime()); 

TimestampDate cả hai đều có thực hiện riêng của phương pháp before. Kiểm tra nó.

3

Vâng, có vẻ như là một trong các tài liệu đặc tính.

Phương thức beforeafter có vẻ là so sánh với phương pháp thứ hai, nhưng không tính đến phần mili giây. Hãy thử chạy nó cho đến khi cả hai TimeStamp rơi vào giây riêng biệt và so sánh hoạt động như mong đợi (tăng giấc ngủ lên 500 để làm cho nó dễ dàng hơn).

Nhân tiện, phương pháp compareTo sẽ tính đến mili giây, vì vậy bạn có thể sử dụng phương pháp đó thay thế.

1

Nếu bạn gọi phương thức Timestamp.before(Timestamp), bạn sẽ nhận được kết quả mong đợi.

Nhưng dường như sử dụng Timestamp làm Date sẽ là một mớ hỗn độn. Bạn phải sử dụng Timestamp làm Timestamptĩnh.

0

Như đã đề cập ở đây

timestamp is a thin wrapper

Một dấu thời gian đơn giản là bổ sung thêm khả năng giữ SQL dấu thời gian phân đoạn giá trị giây (với độ chính xác của nano giây nơi mà vấn đề trong trường hợp của bạn được phát sinh)