tl; डॉ
LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) )
.toEpochSecond()
...
LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
.plusDays( 1 )
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) )
.toEpochSecond()
...
"SELECT * FROM orders WHERE placed >= ? AND placed < ? ; "
...
myPreparedStatement.setObject( 1 , start )
myPreparedStatement.setObject( 2 , stop )
java.time
आप पुरानी पुरानी तारीखों वाली कक्षाओं का उपयोग कर रहे हैं जो अब आधुनिक java.time द्वारा विरासत में ली गई हैं कक्षाओं हैं।
जाहिरा तौर पर आप अपने डेटाबेस में कुछ पूर्णांक प्रकार के कॉलम में एक क्षण का भंडारण कर रहे हैं। वह दुर्भाग्यपूर्ण है। इसके बजाय आपको SQL-standard जैसे किसी प्रकार के कॉलम का उपयोग करना चाहिए TIMESTAMP WITH TIME ZONE
। लेकिन, इस उत्तर के लिए, हमारे पास जो भी है हम उसके साथ काम करेंगे।
यदि आपके रिकॉर्ड मिलीसेकंड के संकल्प के साथ क्षणों का प्रतिनिधित्व करते हैं, और आप पूरे दिन के लिए सभी रिकॉर्ड चाहते हैं, तो हमें समय सीमा की आवश्यकता है। हमारे पास एक शुरुआती पल और एक स्टॉप मोमेंट होना चाहिए। आपकी क्वेरी में केवल एक ही दिनांक-समय मानदंड है जहां इसे एक जोड़ी होना चाहिए था।
LocalDate
वर्ग समय के दिन और समय क्षेत्र के बिना बिना एक दिनांक-केवल मूल्य का प्रतिनिधित्व करता।
एक तिथि निर्धारित करने में एक समय क्षेत्र महत्वपूर्ण है। किसी भी क्षण के लिए, तिथि क्षेत्र के अनुसार दुनिया भर में भिन्न होती है। उदाहरण के लिए, पेरिस फ्रांस में मध्यरात्रि के कुछ मिनट बाद एक नया दिन है जबकि अभी भी "कल" मॉन्ट्रियल क्यूबेक में है ।
यदि कोई समय क्षेत्र निर्दिष्ट नहीं है, तो JVM अपने वर्तमान डिफ़ॉल्ट समय क्षेत्र को स्पष्ट रूप से लागू करता है। वह डिफ़ॉल्ट किसी भी समय बदल सकता है, इसलिए आपके परिणाम भिन्न हो सकते हैं। एक तर्क के रूप में स्पष्ट रूप से अपने वांछित / अपेक्षित समय क्षेत्र को निर्दिष्ट करने के लिए बेहतर है।
के रूप में , या , के प्रारूप में एक उचित समय क्षेत्र नाम निर्दिष्ट करें । कभी इस तरह के रूप में 3-4 पत्र संक्षिप्त नाम का उपयोग या के रूप में वे कर रहे हैं नहीं सच समय क्षेत्र, नहीं मानकीकृत, और यहां तक कि अद्वितीय नहीं (!)।continent/region
America/Montreal
Africa/Casablanca
Pacific/Auckland
EST
IST
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
यदि आप जेवीएम के वर्तमान डिफ़ॉल्ट समय क्षेत्र का उपयोग करना चाहते हैं, तो इसके लिए पूछें और एक तर्क के रूप में पास करें। यदि छोड़ा गया है, तो JVM के वर्तमान डिफ़ॉल्ट को अंतर्निहित रूप से लागू किया जाता है। स्पष्ट होने के लिए बेहतर है, क्योंकि JVM के भीतर किसी भी एप्लिकेशन के किसी भी धागे में किसी भी कोड द्वारा रनटाइम के दौरान किसी भी समय डिफ़ॉल्ट को बदला जा सकता है ।
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
या एक तिथि निर्दिष्ट करें। आप जनवरी-दिसंबर के लिए 1-12 नंबर की संख्या के साथ महीने को निर्धारित कर सकते हैं।
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
या, बेहतर, Month
वर्ष के प्रत्येक महीने के लिए पूर्व निर्धारित, एनम वस्तुओं का उपयोग करें । युक्ति: Month
अपने कोड को और अधिक स्व-दस्तावेजीकरण करने, मान्य मान सुनिश्चित करने और टाइप-सुरक्षा प्रदान करने के लिए केवल कोड संख्या के बजाय अपने कोडबेस में इन ऑब्जेक्ट्स का उपयोग करें ।
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
एक LocalDate
हाथ से, हमें अगले क्षण की एक जोड़ी में बदलने की जरूरत है, दिन की शुरुआत और रोक। मान न लें कि दिन की शुरुआत 00:00:00 बजे से होती है। डेलाइट सेविंग टाइम (DST) जैसी विसंगतियों के कारण, दिन की शुरुआत किसी अन्य समय जैसे 01:00:00 से हो सकती है। तो java.time दिन के पहले क्षण को निर्धारित करते हैं। हम ऐसी किसी भी विसंगति को देखने के ZoneId
लिए एक तर्क देते LocalDate::atStartOfDay
हैं। परिणाम एक है ZonedDateTime
।
ZonedDateTime zdtStart = ld.atStartOfDay( z ) ;
आमतौर पर समय की अवधि को परिभाषित करने का सबसे अच्छा तरीका है, हाफ-ओपन दृष्टिकोण जहां शुरुआत है समावेशी है जबकि अंत अनन्य है । तो एक दिन अपने पहले क्षण के साथ शुरू होता है और अगले दिन के पहले क्षण तक शामिल नहीं होता है।
ZonedDateTime zdtStop = ld.plusDays( 1 ).atStartOfDay( z ) ; // Determine the following date, and ask for the first moment of that day.
पूरे दिन के लिए हमारी क्वेरी SQL कमांड का उपयोग नहीं कर सकती है BETWEEN
। यह कमांड पूरी तरह से बंद है ( []
) (शुरुआत और अंत दोनों समावेशी हैं) जहां हम हाफ-ओपन ( [)
) चाहते हैं। हम मापदंड की एक जोड़ी का उपयोग करते हैं >=
और <
।
आपके कॉलम का नाम खराब है। विभिन्न डेटाबेस द्वारा आरक्षित हजार शब्दों में से किसी से बचें। आइए placed
इस उदाहरण में उपयोग करें।
आपके कोड का उपयोग किया जाना चाहिए ?
में प्लेसहोल्डर का जिसमें हमारे क्षणों को निर्दिष्ट करना है।
String sql = "SELECT * FROM orders WHERE placed >= ? AND placed < ? ; " ;
लेकिन हमारे पास है ZonedDateTime
हाथ में वस्तुएं हैं, जबकि आपका डेटाबेस जाहिरा तौर पर पूर्णांक को संग्रहीत कर रहा है जैसा कि ऊपर चर्चा की गई है। यदि आपने अपने कॉलम को ठीक से परिभाषित किया था तो हम बस ZonedDateTime
JDBC 4.2 या उसके बाद वाले किसी भी JDBC ड्राइवर के साथ ऑब्जेक्ट पास कर सकते हैं ।
लेकिन इसके बजाय हमें पूरे सेकंड में एक गिनती-से-युग प्राप्त करने की आवश्यकता है। मुझे लगता है कि यूटीसी में 1970 की पहली तारीख आपके लिए संदर्भ की तारीख होगी। डेटा हानि से सावधान रहें, जैसा किZonedDateTime
कक्षा नैनोसेकंड रिज़ॉल्यूशन में सक्षम है। किसी भी भिन्नात्मक दूसरे को निम्न पंक्तियों में काट दिया जाएगा।
long start = zdtStart().toEpochSecond() ; // Transform to a count of whole seconds since 1970-01-01T00:00:00Z.
long stop = zdtStop().toEpochSecond() ;
अब हम उन पूर्णांकों को हमारे एसक्यूएल कोड से ऊपर पारित करने के लिए तैयार हैं।
PreparedStatement ps = con.prepareStatement( sql );
ps.setObject( 1 , start ) ;
ps.setObject( 2 , stop ) ;
ResultSet rs = ps.executeQuery();
जब आप अपने पूर्णांक मानों को पुनः प्राप्त करते हैं ResultSet
, तो आप Instant
ऑब्जेक्ट्स (हमेशा यूटीसी में), या ZonedDateTime
ऑब्जेक्ट्स (एक निर्दिष्ट क्षेत्र के साथ) में बदल सकते हैं।
Instant instant = rs.getObject( … , Instant.class ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
जावा के बारे में
Java.time ढांचे जावा 8 और बाद में बनाया गया है। इन कक्षाओं परेशानी वर्ष प्रतिस्थापित विरासत जैसे तिथि-समय कक्षाएं java.util.Date
, Calendar
, औरSimpleDateFormat
।
Joda समय परियोजना, अब में रखरखाव मोड , के लिए प्रवास की सलाह है java.time कक्षाएं।
अधिक जानने के लिए, Oracle ट्यूटोरियल देखें । और कई उदाहरणों और स्पष्टीकरणों के लिए ढेर अतिप्रवाह खोजें। विशिष्टता JSR 310 है ।
Java.time कक्षाएं कहाँ से प्राप्त करें?
ThreeTen-अतिरिक्त परियोजना अतिरिक्त कक्षाओं के साथ java.time फैली हुई है। यह परियोजना java.time के संभावित भविष्य के अतिरिक्त के लिए एक साबित जमीन है। आप यहाँ कुछ उपयोगी वर्गों जैसे मिल सकता है Interval
, YearWeek
, YearQuarter
, और अधिक ।