समय के साथ वर्तमान स्थिति

जब से JDBC का आविष्कार किया गया था और इसके इंटरफेस को मानकीकृत किया गया था, तब से 20 साल बीत चुके हैं और इस दौरान बहुत कुछ बदल गया है।

सबसे पहले, दुनिया वैश्विक हो गई है और अब एक सर्वर दुनिया भर के उपयोगकर्ताओं की सेवा कर सकता है। इंटरनेट की गति तेज हो गई है। इसलिए, समय के साथ काम करने के लिए SQL में एक और डेटा प्रकार जोड़ा गया था । अब प्रकार इस तरह दिखते हैं:

  • दिनांक - दिनांक संग्रहीत करता है: वर्ष, महीना, दिन।
  • समय - स्टोर समय: घंटे, मिनट, सेकंड।
  • TIMESTAMP - समय में एक विशिष्ट बिंदु संग्रहीत करता है: दिनांक, समय और मिलीसेकंड।
  • टाइम ज़ोन के साथ टाइमस्टैम्प - टाइमस्टैम्प और टाइम ज़ोन (ज़ोन का नाम या ऑफ़सेट)।

दूसरे, जावा ने वैश्विक समय प्रबंधन के लिए डेटटाइम एपीआई की शुरुआत की। इसमें निम्न वर्ग हैं:

  • दिनांक और समय :
    • लोकलडेट
    • स्थानीय समय
  • सटीक पल :
    • java.time.Instant
    • java.time.LocalDateTime
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime
  • समय क्षेत्र के साथ समय :
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime

तीसरा दिलचस्प बिंदु यह है कि कई SQL क्लाइंट अपने स्थानीय क्षेत्र में पहले से ही सर्वर से समय प्राप्त करना चाहेंगे । बेशक, आप चलते-फिरते समय को परिवर्तित कर सकते हैं, लेकिन यह सुविधाजनक नहीं है, और गलतियाँ हैं।

उदाहरण के लिए, मैं डेटाबेस से आज के लिए सभी कार्य प्राप्त करना चाहता हूं। SQL सर्वर के पास इसके लिए एक CURDATE() फ़ंक्शन है। केवल यहां सर्वर यूएसए में है, और मैं जापान में हूं। और मैं चाहूंगा कि वह "मेरा आज" के लिए सभी रिकॉर्ड लौटाए, न कि "उसका आज"।

सामान्य तौर पर, SQL सर्वर को अलग-अलग समय क्षेत्रों में क्लाइंट्स के साथ स्मार्ट तरीके से काम करने में सक्षम होना चाहिए।

आधुनिक समस्याओं के लिए आधुनिक समाधानों की आवश्यकता होती है

सिद्धांत रूप में, जावा डेटटाइम एपीआई से नए प्रकार और एसक्यूएल से प्रकार को आसानी से मैप किया जा सकता है। जावा में DATE प्रकार का प्रतिनिधित्व करने के लिए , आपको JDK 8 DateTime API से java.time.LocalDate क्लास का उपयोग करने की आवश्यकता है।

डेटाबेस से TIME प्रकार को जावा से दो प्रकारों द्वारा दर्शाया जा सकता है: java.time.LocalTime और java.time.OffsetTime । कुछ भी जटिल नहीं है।

समय में एक विशिष्ट बिंदु, डेटाबेस में TIMESTAMP प्रकार द्वारा दर्शाया गया, जावा में 4 प्रकारों द्वारा दर्शाया जा सकता है:

  • java.time.Instant
  • java.time.LocalDateTime
  • java.time.OffsetDateTime
  • java.time.ZonedDateTime

और अंत में, TIMESTAMP with TIME ZONE को दो प्रकार से दर्शाया जा सकता है:

  • java.time.OffsetDateTime
  • java.time.ZonedDateTime

चूंकि आप डेटटाइम एपीआई से पहले ही परिचित हैं, इसलिए इस मामले को याद रखना आपके लिए मुश्किल नहीं होगा :)

मैं इसे तालिका के रूप में लिखूंगा, जिससे यह आसान हो जाएगा:

एसक्यूएल प्रकार जावा प्रकार
तारीख java.time.LocalDate
समय java.time.LocalTime
java.time.OffsetTime
TIMESTAMP java.time.Instant
Java.time.LocalDateTime
Java.time.OffsetDateTime
Java.time.ZonedDateTime
टाइम ज़ोन के साथ टाइमस्टैम्प java.time.OffsetDateTime
_

तारीख मिल रही है

मेरे पास तुम्हारे लिए अच्छी खबर है। पहले लंबे समय में। हम getDate() मेथड की सीमा को पार कर सकते हैं , जो एक java.sql डेट टाइप देता है।

मुद्दा यह है कि वस्तुपरिणाम सेटएक और दिलचस्प तरीका है - getObject() । यह विधि दो पैरामीटर लेती है: एक स्तंभ और एक प्रकार, और दिए गए प्रकार में परिवर्तित स्तंभ का मान लौटाता है। विधि का सामान्य रूप इस प्रकार है:

ClassName Name = getObject(column, ClassName);

और यदि आप DATE प्रकार को java.time.LocalDate प्रकार में कनवर्ट करना चाहते हैं , तो आपको कुछ लिखने की आवश्यकता है:

LocalDate localDate = results.getObject(4, LocalDate.class);

और सामान्य रूप से किसी भी टाइमस्टैम्प को प्रकारों के समूह में परिवर्तित किया जा सकता है:

java.time.Instant instant = results.getObject(9, java.time.Instant.class);
java.time.LocalDateTime local = results.getObject(9, java.time. LocalDateTime.class);
java.time.OffsetDateTime offset = results.getObject(9, java.time. OffsetDateTime.class);
java.time.ZonedDateTime zoned = results.getObject(9, java.time. ZonedDateTime.class);

महत्वपूर्ण! यदि आपके पास पुराना MySQL JDBC ड्राइवर है तो यह कोड काम नहीं करेगा । अपने pom.xml में लिखे गए "mysql-कनेक्टर-जावा" के संस्करण पर ध्यान दें, या प्रोजेक्ट सेटिंग्स में लाइब्रेरी में जोड़ा गया।

वैसे, आप आदिम प्रकारों के लिए शून्य को स्टोर करने में असमर्थता प्राप्त कर सकते हैं। यदि तालिका स्तंभ INT प्रकार का है, तो इससे शून्य होने के कुछ तरीके हैं। नीचे उदाहरण देखें:

Integer id1 = results.getObject(8, Integer.class);    	 // this will work
Integer id2 = results.getObject(8, int.class);                 //this will also work
int id3 = results.getObject(8,  Integer.class);            	//method will return null, JVM will throw NPE
int id4 = results.getObject(8,  int.class);                    	//method will return null, JVM will throw NPE

MySQL में टाइमज़ोन सेटिंग

MySQL के साथ भी बहुत सी दिलचस्प बातें हुईं। जैसा कि आप जानते हैं, MySQL कनेक्शन बनाते समय, आप इसमें विभिन्न पैरामीटर जोड़ सकते हैं :
mysql://localhost:3306/db_scheme?Name=meaning&Name=meaning

इसलिए, MySQL में टाइम ज़ोन के साथ काम करने के लिए तीन पैरामीटर जोड़े गए हैं। जब आप सर्वर से कनेक्शन स्थापित करते हैं तो आप इन पैरामीटर को पास कर सकते हैं।

नीचे मैं उनके साथ एक टेबल दूंगा:

पैरामीटर मान डिफ़ॉल्ट मान
कनेक्शनटाइमज़ोन स्थानीय | सर्वर | user-zone सर्वर
फ़ोर्सकनेक्शनटाइमज़ोनटूसेशन सच | असत्य सत्य
इंस्टेंट सच | असत्य असत्य

कनेक्शनटाइमज़ोन पैरामीटर का उपयोग करके , हम समय क्षेत्र (समय क्षेत्र) का चयन करते हैं जिसमें सभी अनुरोध निष्पादित किए जाएंगे। ग्राहक के दृष्टिकोण से, सर्वर निर्दिष्ट समय क्षेत्र में चल रहा है।

ForceConnectionTimeZoneToSession पैरामीटर के कारण सत्र time_zone चर को अनदेखा किया जाता है और कनेक्शन TimeZone से बदल दिया जाता है।

अंत में, PreserveInstants पैरामीटर JVM के टाइमज़ोन और कनेक्शनटाइमज़ोन के बीच सटीक-समय-रूपांतरण को नियंत्रित करता है।

सबसे आम विन्यास हैं:

  • कनेक्शनटाइमज़ोन=लोकल और फ़ोर्सकनेक्शनटाइमज़ोनटूसेशन=झूठा - पुराने MySQL JDBC ड्राइवर संस्करण 5.1 के अनुरूप है useLegacyDatetimeCode=true के साथ।

  • connectionTimeZone=LOCAL और forceConnectionTimeZoneToSession=true एक नया मोड है जो दिनांक और समय मानों को संभालने का सबसे प्राकृतिक तरीका प्रदान करता है।

  • कनेक्शनटाइमज़ोन = सर्वर और संरक्षित इंस्टेंट = सच - पुराने MySQL जेडीबीसी ड्राइवर संस्करण 5.1 के अनुरूप उपयोग लिगेसीडेटटाइमकोड = गलत के साथ।

  • कनेक्शनटाइमज़ोन = उपयोगकर्ता_परिभाषित और संरक्षित इंस्टेंट = सच - उस स्थिति को दूर करने में मदद करता है जहां सर्वर के समय क्षेत्र को कनेक्टर द्वारा पहचाना नहीं जा सकता क्योंकि यह सीईटी / सीईएसटी जैसे सामान्य संक्षिप्त नाम के रूप में सेट है।

हां, तारीखें एक रोचक विषय हैं और इनके साथ कई समस्याएं भी हैं। जैसा कह रहा है: यह डरावना है, ज़ाहिर है, लेकिन मैं या तो नाराज नहीं हूँ! :)