मैंने कुछ परीक्षण जेडीबीसी कोड को एक साथ रखा ताकि यह पता चल सके कि वास्तव में क्या होता है। परिणाम दिलचस्प थे। ओरेकल में तीन करीबी संबंधित डेटाटाइप हैं: TIMESTAMP
, TIMESTAMP WITH TIME ZONE
, और TIMESTAMP WITH LOCAL TIME ZONE
। मैंने सटीक कोड लिया, और इसे दो अलग-अलग बक्से से चलाया, एक "अमेरिका/न्यू_यॉर्क" टाइमज़ोन में, और एक यूटीसी पर चल रहा है। दोनों ने यूटीसी में चल रहे एक ही डेटाबेस को मारा। मैं ओरेकल 11.2.0.2.0 ड्राइवर का उपयोग कर रहा था।
TIMESTAMP
कॉलम जावा कोड को निष्पादित मशीन पर स्थानीय समय पर सेट किया गया था। कोई समय क्षेत्र अनुवाद नहीं किया गया था।
TIMESTAMP WITH TIME ZONE
स्तंभ के लिए समय जो कुछ समय क्षेत्र JDBC ग्राहक में किया गया था अनुवाद।
TIMESTAMP WITH LOCAL TIME ZONE
स्तंभ भी करने के लिए समय जो कुछ समय क्षेत्र JDBC ग्राहक में किया गया था अनुवाद।
This article है, जो थोड़ा पुराना है , इंगित करता है कि TIMESTAMP WITH TIME ZONE
बहुत अधिक बेकार है यदि आप इंडेक्स या विभाजन जैसे कुछ भी करना चाहते हैं। हालांकि, ऐसा लगता है कि TIMESTAMP WITH LOCAL TIME ZONE
बहुत उपयोगी हो सकता है। (सुनिश्चित नहीं है कि यदि आप सर्वर का समय क्षेत्र बदलते हैं तो क्या होता है, लेकिन यह जेडीबीसी क्लाइंट के स्थानीय समय क्षेत्र के बारे में बुद्धिमान प्रतीत होता है)। मुझे इन डेटाटाइप के साथ इंडेक्सिंग व्यवहार आदि का परीक्षण करने का मौका नहीं मिला है।
यदि आप अपने पर्यावरण में अपने परीक्षणों को पुन: पेश करना चाहते हैं तो नीचे मेरे नमूना वर्ग में चिपकाएं।
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.Date;
// create table x_tst_ts_tab(
// os_name varchar(256)
// ts timestamp,
// ts_with_tz timestamp with time zone,
// ts_with_local_tz timestamp with local time zone
//)
class TSTest {
public static final void main(String[] argv) throws Exception {
Class.forName("oracle.jdbc.OracleDriver");
Connection conn = DriverManager.getConnection(
"your_connection_string",
"your_user_name",
"your_password");
try {
// Insert some data
Date nowDate = new Date();
Timestamp nowTimestamp = new Timestamp(nowDate.getTime());
PreparedStatement insertStmt = conn.prepareStatement(
"INSERT INTO x_tst_ts_tab"
+ " (os_name, ts, ts_with_tz, ts_with_local_tz)"
+ " VALUES (?, ?, ?, ?)");
try {
insertStmt.setString(1, System.getProperty("os.name"));
insertStmt.setTimestamp(2, nowTimestamp);
insertStmt.setTimestamp(3, nowTimestamp);
insertStmt.setTimestamp(4, nowTimestamp);
insertStmt.executeUpdate();
} finally {
try {
insertStmt.close();
} catch (Throwable t) {
// do nothing
}
}
System.out.println("os_name, ts, ts_with_tz, ts_with_local_tz");
// Read back everything in the DB
PreparedStatement selectStmt = conn.prepareStatement(
"SELECT os_name, ts, ts_with_tz, ts_with_local_tz"
+ " FROM dom_fraud_beacon.x_tst_ts_tab");
ResultSet result = null;
try {
result = selectStmt.executeQuery();
while (result.next()) {
System.out.println(
String.format("%s,%s,%s,%s",
result.getString(1),
result.getTimestamp(2).toString(),
result.getTimestamp(3).toString(),
result.getTimestamp(4).toString()
));
}
} finally {
try {
result.close();
} catch (Throwable t) {
// do nothing
} finally {
try {
selectStmt.close();
} catch (Throwable t) {
// do nothing
}
}
}
} finally {
try {
conn.close();
} catch (Throwable t) {
// do nothing
}
}
}
}
आप इसे अंत में क्यों कर रहे हैं जब डेटाबेस इसे केंद्रीय रूप से कर सकता है? – Tim
मैं समझने की कोशिश कर रहा हूं कि जेडीबीसी चालक क्या करता है। ऐसा लगता है कि, मेरे लॉग में, यह ओरेकल को स्थानीय समय का प्रतिनिधित्व करने वाली एक स्ट्रिंग भेज रहा है। यह मुझे परेशान करता है। – drinian
[यह डॉक्टर] (http://docs.oracle.com/javase/1.3/docs/guide/jdbc/spec2/jdbc2.1.frame10.html) बताता है कि जेडीबीसी चालक द्वारा भेजा गया क्या सामान्य नहीं है (यानी यूटीसी) टाइमस्टैम्प लेकिन एक स्थानीय टाइमज़ोन टाइमस्टैम्प (जिसे मैं यादृच्छिक कहूंगा) और सर्वर को ड्राइवर के पास सर्वर के टाइमज़ोन का उपयोग करके अपनी तिथि की गणना करना चाहिए। यह आपकी खोज के अनुसार है। और हाँ यह परेशान है। –