2009-07-01 47 views
59

I Have a prepared statementLàm thế nào để sử dụng Joda thời gian với java.sql.Timestamp

INSERT INTO mst(time) VALUES (?); 

mà thời gian là loại Timestamp trong một cơ sở dữ liệu PostgreSQL.
Tôi đang chèn một đối tượng Joda-TimeDateTime hoặc tôi nên nói là tôi đang cố gắng. Tôi không thể tìm cách chuyển đổi đối tượng DateTime thành java.sql.Timestamp. Tôi đã đọc tài liệu Joda-Time và không thấy tham chiếu đến điều này.

Cảm ơn.

Trả lời

84

Bạn có thể chuyển đổi DateTime Joda thành dài (millis kể từ thời đại), sau đó tạo Dấu thời gian từ đó.

DateTime dateTime = new DateTime(); 
Timestamp timeStamp = new Timestamp(dateTime.getMillis()); 
+6

Trường hợp về thành phần TimeZone? Bạn chỉ có "sao chép" ngày tháng và thời gian nhưng không phải là múi giờ có thể ảnh hưởng đến giá trị thực tế ... –

+5

Bạn có thể giải thích về ý nghĩa của mình không? dateTime.getMillis() trả về mili giây từ epoch, nó sẽ tính đến múi giờ. –

+6

Cần lưu ý rằng thời gian joda không lưu trữ nano giây trong khi Dấu thời gian thực hiện. Bất kỳ chuyển đổi nào giữa hai sẽ mất độ chính xác nano giây. – Gili

9

Trình tạo DateTime của JodaTime có thể xử lý điều này cho bạn ngay bây giờ. (Tôi không chắc chắn nếu điều đó là sự thật khi câu hỏi được đăng, nhưng đó là một kết quả top Google vì vậy tôi figured tôi muốn thêm một giải pháp mới hơn.)

Có một vài lựa chọn API:

public DateTime(Object instant); 
public DateTime(Object instant, DateTimeZone zone); 

Cả hai tùy chọn đều chấp nhận java.sql.Timestamp bởi vì nó mở rộng java.util.Date, nhưng Nanoseconds sẽ bị bỏ qua (sàn), bởi vì DateTime và Date chỉ có độ phân giải mili giây *. Không có múi giờ cụ thể, nó sẽ mặc định là DateTimeZone.UTC.

< Chế độ chiến thuật >
"Độ phân giải" là số lượng chữ số được cung cấp. "Độ chính xác" là độ chính xác của biểu diễn. Ví dụ, DateTime của MSSQL có độ phân giải mili giây, nhưng chỉ ~ 1/3 của độ chính xác thứ hai (DateTime2 có độ phân giải biến và độ chính xác cao hơn).
</Didactic Chế độ >

UTC Timestamp với Mili giây Độ phân giải Ví dụ:

new DateTime(resultSet.getTimestamp(1)); 

Nếu bạn đang sử dụng dấu thời gian VỚI TIME ZONE trong cơ sở dữ liệu của bạn thì bạn không thể sử dụng java.sql.Timestamp, bởi vì nó không hỗ trợ múi giờ. Bạn sẽ phải sử dụng ResultSet # getString và phân tích cú pháp chuỗi.

Timestamp không Time Zone với Thứ hai Nghị quyết Ví dụ **:

LocalDateTime dt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss") 
    .parseLocalDateTime(resultSet.getString(1)); 

UTC Timestamp với Thứ hai Nghị quyết Ví dụ **:

DateTime dt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss") 
    .parseDateTime(resultSet.getString(1)); 

Timestamp với Time Zone (bù đắp định dạng) với Thứ hai Nghị quyết Ví dụ **:

DateTime dt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss Z") 
    .parseDateTime(resultSet.getString(1)); 

Phần thưởng: DateTimeFormat # forPattern static đồng minh lưu trữ các trình phân tích cú pháp theo mẫu để bạn không phải làm như vậy.

< Didactic Chế độ >
Tôi thường khuyên bạn nên sử dụng một String trong mô hình DBO của bạn để làm cho độ phân giải rõ ràng và tránh tạo ra đối tượng trung gian. (Là 2013-11-14 09:55:25 bằng 2013-11-14 09: 55: 25.000?Tôi thường cố gắng phân biệt giữa "đối tượng mô hình cơ sở dữ liệu" để tối ưu hóa mối quan tâm bảo tồn dữ liệu và "đối tượng mô hình kinh doanh" tối ưu hóa việc sử dụng mức dịch vụ với lớp chuyển đổi/ánh xạ ở giữa. Tôi thấy có DAO dựa trên CRUD tạo ra các đối tượng kinh doanh trực tiếp có xu hướng trộn lẫn các ưu tiên và tối ưu hóa cho không, ném ngoại lệ từ những nơi không mong muốn vì các trường hợp cạnh bị bỏ sót. Có một lớp chuyển đổi rõ ràng cũng cho phép bạn thêm xác nhận nếu cần thiết, như nếu bạn không kiểm soát nguồn dữ liệu. Tách các mối quan tâm cũng giúp dễ dàng kiểm tra từng lớp một cách độc lập.
</Chế độ chiến thuật >

* Nếu bạn cần giải quyết đến độ phân giải nano giây trong mô hình kinh doanh, bạn sẽ phải sử dụng một thư viện khác.

** Định dạng chuỗi dấu thời gian có thể khác nhau giữa các cơ sở dữ liệu, không chắc chắn.

+0

Về nano giây… FYI, [JSR 310: API ngày và giờ] (http://jcp.org/en/jsr/detail?id=310) được tích hợp vào Java 8 và người kế thừa Joda-Time, thực sự hỗ trợ nano giây độ phân giải. Hãy nhớ rằng nhiều đồng hồ của máy tính không giữ thời gian cho mức độ chi tiết đó. Ngoài ra: lưu ý thú vị từ đặc tả JSR: * Các lớp này sử dụng độ chính xác nano giây. Các lớp học có đủ độ chính xác để biểu diễn bất kỳ tức thời nano giây nào trong độ tuổi hiện tại của vũ trụ. * –

+0

Tôi ước họ sẽ sửa lỗi trong spec đó ... Java không kiểm soát độ chính xác của phần cứng và độ chính xác là hàm chính xác và tính chính xác (hoặc 'đúng').Các lớp có độ phân giải nano giây và đủ kích thước trong bộ nhớ để biểu thị một số lượng rất lớn nano giây. – KarlKFI

+0

Đối với xác nhận của bạn về mức độ chi tiết: một số hệ thống không có độ phân giải nano giây và một số hệ thống không có độ chính xác hoặc độ chính xác nano giây. System.nanoTime() có thể thêm số 0 vào bất kỳ hệ thống nào mà hệ điều hành không cung cấp độ phân giải nano giây, nhưng chỉ làm tăng độ phân giải, không chính xác, chính xác hoặc chính xác. Đây là nguồn thông tin chi tiết nhất mà tôi có thể tìm thấy trong thuật ngữ: http://www.tutelman.com/golf/measure/precision.php – KarlKFI

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