2009-10-02 34 views
7

Tôi có một cột JDBC ngày, mà nếu ai sử dụng getDate là có được 'ngày' phần duy nhất 02 Tháng 10 2009 nhưng nếu tôi sử dụng getTimestamp tôi nhận được đầy đủ 'ngày' 02 tháng 10 năm 2009 13: 56: 78: 890. Đây là excatly những gì tôi muốn.JDBC Timestamp & ngày giờ hành

Tuy nhiên 'ngày' được trả về bởi getTimestamp 'bỏ qua' các giá trị GMT, giả sử ngày; ngày 2 tháng 10 năm 2009 13: 56: 78: 890, tôi kết thúc nhận ngày 2 tháng 10 năm 2009 15: 56: 78: 890

ngày của tôi được lưu lại dưới dạng một ngày + 2GMT trên cơ sở dữ liệu nhưng máy chủ ứng dụng theo giờ GMT tức là 2 giờ sau

làm thế nào vẫn có thể nhận ngày của tôi như là, 02 tháng mười năm 2009 13: 56: 78: 890

Sửa

tôi nhận được ngày 2 trên các mặt hàng mà vào giờ GMT +2

Trả lời

12

Đó là sự khác biệt giữa Dấu thời gian và các loại thời gian khác trong MySQL. Dấu thời gian được lưu dưới dạng time_t Unix trong UTC nhưng các loại ngày/giờ lưu trữ khác theo nghĩa đen mà không có thông tin vùng.

Khi bạn gọi getTimestamp(), trình điều khiển JDBC MySQL chuyển đổi thời gian từ GMT thành múi giờ mặc định nếu loại là dấu thời gian. Nó thực hiện không có chuyển đổi như vậy cho các loại khác.

Bạn có thể thay đổi loại cột hoặc tự thực hiện chuyển đổi. Tôi đề nghị phương pháp tiếp cận cũ.

+0

từ khóa ** chuyển đổi **, đó là lý do tại sao tôi nhận được +2 giờ – n002213f

+0

Tôi bị nhầm lẫn, nếu chuyển đổi hoạt động bình thường, không nên nhìn thấy ngày ít hơn 2 giờ, thay vì ? – wds

+0

@wds - kiểm tra chỉnh sửa và phản hồi của tôi – n002213f

4

Bạn nên lưu ý rằng java.util.Date (và cũng là java.sql.Datejava.sql.Timestamp, là các lớp con của java.util.Date) không biết gì về múi giờ, hay đúng hơn, chúng luôn ở dạng UTC.

java.util.Date và các lớp con của nó không gì hơn một vùng chứa cho giá trị "số mili giây kể từ 01-01-1970, 12:00 giờ UTC".

Để hiển thị ngày trong múi giờ cụ thể, hãy chuyển đổi ngày thành một chuỗi bằng cách sử dụng đối tượng java.text.DateFormat. Đặt múi giờ trên đối tượng đó bằng cách gọi phương thức setTimeZone(). Ví dụ:

Date date = ...; // wherever you get this from 

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

// Make the date format show the date in CET (central European time) 
df.setTimeZone(TimeZone.getTimeZone("CET")); 

String text = df.format(date); 
0

Từ post này tôi đã đi đến kết luận rằng JDBC không lấy múi giờ cho Timestamp (Tôi không nghĩ hỗ trợ MS SQL này là tốt, hầu hết các kết quả của Google trỏ đến Oracle)

Khi JDBC getTimestamp phương pháp được gọi là nó chỉ được 'mili giây' phần và tạo đối tượng Ngày với máy chủ TimeZone, là GMT.

Khi đối tượng Ngày tháng này được trình bày cho khách hàng của tôi là +2 GMT, nó thêm 2 giờ là chênh lệch tiêu chuẩn dẫn đến số giờ thêm.

Tôi đã sửa lỗi này bằng cách xóa chênh lệch thời gian khỏi ngày tôi truy xuất tức là chuyển đổi thành Ngày GMT thực sự.

3

Tôi đã gặp sự cố tương tự vào ngày khác mà thành phần thời gian bị cắt bớt từ một số ngày.

Chúng tôi đã thu hẹp nó xuống sự khác biệt trong các phiên bản Trình điều khiển Oracle.

On FAQ Oracle có một phần về vấn đề này:


select sysdate from dual; ...while(rs.next()) 

Trước 9201, đây sẽ trở lại: getObject cho sysdate: java.sql.Timestamp < < < < getDate cho sysdate : java.sql.Date getTimetamp cho sysdate: java.sql.Timestamp

Từ 9201 trở đi sau đây sẽ được thử lại urned

getObject cho sysdate: java.sql.Date < < < < < getDate cho sysdate: java.sql.Date >> không thay đổi getTimetamp cho sysdate: java.sql.Timestamp >> không thay đổi

Lưu ý: java.sql.Date không có phần thời gian trong khi java.sql.Timestamp làm.

Với thay đổi này trong ánh xạ Datatype, một số ứng dụng sẽ không thành công và/hoặc tạo kết quả không chính xác khi trình điều khiển JDBC được nâng cấp từ trình điều khiển JBDC 8i/9iR1 lên 920x. Để duy trì tính tương thích và giữ cho các ứng dụng hoạt động sau khi nâng cấp, cờ tương thích đã được cung cấp. Nhà phát triển hiện có một số tùy chọn:

  1. Sử dụng oracle.jdbc.V8Tương thích tương thích.

Trình điều khiển JDBC không phát hiện phiên bản cơ sở dữ liệu theo mặc định. Để thay đổi lá cờ tương thích để xử lý kiểu dữ liệu dấu thời gian, sở hữu kết nối

'oracle.jdbc.V8Compatible'

có thể được thiết lập để 'true' và người lái xe cư xử như nó cư xử trong 8I, 901x, 9 200 (với đối với TIMESTAMP).

Theo mặc định, cờ được đặt thành 'sai'. Trong phương thức khởi tạo OracleConnection, trình điều khiển có được phiên bản máy chủ và đặt cờ tương thích một cách thích hợp.

java.util.Properties prop=newjava.util.Properties(); 
prop.put("oracle.jdbc.V8Compatible","true"); 
prop.put("user","scott"); 
prop.put("password","tiger"); 
String url="jdbc:oracle:thin:@host:port:sid"; 
Connection conn = DriverManager.getConnection(url,prop); 

Với JDBC 10.1.0.x, thay vì tài sản kết nối, tài sản hệ thống sau đây có thể được sử dụng: java -Doracle.jdbc.V8Compatible = true ..... Lưu ý: Cờ này là một khách hàng chỉ cờ điều chỉnh Dấu thời gian và ánh xạ ngày. Nó không ảnh hưởng đến bất kỳ tính năng Cơ sở dữ liệu nào.

'2. Sử dụng set/getDate và set/getTimestamp khi xử lý kiểu dữ liệu cột Date và TimeStamp cho phù hợp.

Máy chủ 9i hỗ trợ cả kiểu cột Ngày và Dấu thời gian DATE được ánh xạ tới java.sql.Date và TIMESTAMP được ánh xạ tới java.sql.Timestamp.


Vì vậy, cho hoàn cảnh của tôi, tôi đã có mã như thế này:

import java.util.Date; 
Date d = rs.getDate(1); 

Với 9i Tôi đã nhận được một java.sql.Timestamp (mà là một lớp con của java.util.Date) để tất cả mọi thứ đã được groovy và tôi đã có giờ và phút của tôi.

Nhưng với 10g, cùng một mã bây giờ nhận được một java.sql.Date (cũng là một lớp con của java.util.Date để nó vẫn biên dịch) nhưng HH: MM bị TRUNCATED !!.

Giải pháp thứ hai khá dễ dàng đối với tôi - chỉ cần thay thế getDate bằng getTimestamp và bạn sẽ không sao. Tôi đoán đó là một thói quen xấu.

+0

cảm ơn vì một Jim, được đánh giá cao nhất. – n002213f

0
private Date convertDate(Date date1) throws ParseException { 
     SimpleDateFormat sdfFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
     String dateStr = sdfFormatter.format(date1); 
     SimpleDateFormat sdfParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
     sdfParser.setTimeZone(TimeZone.getTimeZone("GMT")); 
     return sdfParser.parse(dateStr); 
    } 
Các vấn đề liên quan