2017-04-18 13 views
7

में जावा 8 लोकलडेट और लोकलडेटाइम के साथ हाइबरनेट, यह एक निहित/सीधे आगे जवाब के साथ एक बेवकूफ सवाल हो सकता है, लेकिन किसी भी तरह से मैं इसके चारों ओर अपने सिर को लपेटने में सक्षम नहीं हूं।डाटाबेस

मेरी आवश्यकता डेटाबेस में यूटीसी टाइमज़ोन में दिनांक-समय & स्टोर करने के लिए है। मैं जावा 8 के LocalDate & LocalDateTime का उपयोग अपने हाइबरनेट इकाइयों में कर रहा हूं।

क्या यह सही है LocalDate & LocalDateTime में उनके साथ जुड़े समय क्षेत्र नहीं है?

यदि नहीं, तो क्या मुझे अच्छी पुरानी (या विरासत?) Date & Timestamp का उपयोग करने के लिए वापस आना चाहिए?

या मुझे जावा 8 के Instant का उपयोग करना चाहिए? यदि Instant का उपयोग कर रहे हैं, तो क्या समय के बिना ही तारीख भाग को स्टोर करने की संभावना होगी?

यदि यह कोई फर्क पड़ता है, तो डेटाबेस जिस पर मैं उन्हें काम करना चाहता हूं वह MySQL & SQL सर्वर है।

फिर, यदि यह और अंतर बनाता है, तो यह एक वसंत बूट एप्लिकेशन है।

धन्यवाद !!

उत्तर

12

"स्थानीय ..." प्रकार जानबूझकर समय क्षेत्र की धारणा नहीं। तो वे टाइमलाइन पर एक पल का प्रतिनिधित्व करते हैं। LocalDateTime संभावित क्षणों की अस्पष्ट श्रृंखला का प्रतिनिधित्व करता है लेकिन ऑफ़सेट या समय क्षेत्र निर्दिष्ट करने तक इसका कोई वास्तविक अर्थ नहीं है। इसका अर्थ है ZonedDateTime प्राप्त करने के लिए।

उदाहरण के लिए, यह कहना है कि क्रिसमस इस साल 25 दिसंबर की पहली पल में शुरू होता है, हम कहते हैं:

LocalDateTime ldt = LocalDateTime.of(2017 , 12 , 25 , 0 , 0 , 0 , 0); 

लेकिन आधी रात के उस स्ट्रोक पश्चिम की तुलना में पूर्व में पहले होता है।

यही कारण है कि elves 'logistics विभाग प्रशांत क्षेत्र में Kiribati से शुरू होने वाले सांता के मार्ग को मानचित्र करता है, जो यूटीसी से 14 घंटे पहले दुनिया का सबसे पुराना समय क्षेत्र है। वहां पहुंचने के बाद, वे सांता को पश्चिम की ओर अपने मध्यरात्रि के लिए न्यूजीलैंड जैसे स्थानों पर पहुंचाते हैं। फिर एशिया के बाद मध्यरात्रि के लिए। फिर भारत, और कई घंटों बाद, मध्यरात्रि के लिए कई घंटों बाद यूरोप और उत्तरी अमेरिका के पूर्वी तट को कुछ घंटों बाद मध्यरात्रि के लिए पहुंचा। इन सभी स्थानों का अनुभव किया गया कि समानLocalDateTime अलग-अलग क्षणों पर, प्रत्येक डिलीवरी विभिन्नZonedDateTime ऑब्जेक्ट द्वारा दर्शाती है।

तो ...

  • आप क्रिसमस 25 आधी रात के बाद शुरू करने की अवधारणा रिकॉर्ड करना चाहते हैं, तो एक LocalDateTime का उपयोग करें और प्रकार TIMESTAMP WITHOUT TIME ZONE के एक डेटाबेस स्तंभ में लिखें।
  • यदि आप प्रत्येक डिलीवरी सांता के सटीक पल को रिकॉर्ड करना चाहते हैं, तो ZonedDateTime का उपयोग करें और TIMESTAMP WITH TIME ZONE के डेटाबेस कॉलम में लिखें।

उस दूसरे बुलेट के बारे में, जागरूक रहें कि लगभग हर डेटाबेस सिस्टम यूटीसी को डेट-टाइम समायोजित करने और यूटीसी मूल्य को स्टोर करने के लिए ज़ोन जानकारी का उपयोग करेगा। कुछ जोन जानकारी भी सहेजते हैं, लेकिन कुछ पोस्टग्रेस यूटीसी में समायोजित करने के लिए इसका उपयोग करने के बाद जोन जानकारी को त्याग देते हैं। तो "समय क्षेत्र के साथ" एक गलत नामक है, जिसका अर्थ है "समय क्षेत्र के लिए सम्मान के साथ"। यदि आप उस मूल क्षेत्र को याद रखने की परवाह करते हैं, तो आपको इसके नाम को एक अलग कॉलम में स्टोर करने की आवश्यकता हो सकती है।

Local… प्रकारों का उपयोग करने का एक अन्य कारण भविष्य की नियुक्तियों के लिए है। राजनेता अक्सर अपने क्षेत्राधिकार के अपने समय क्षेत्र (ओं) को बदलने का आनंद लेते हैं। वे डेलाइट सेविंग टाइम (डीएसटी) को अपनाना पसंद करते हैं। उनके डीएसटी कटओवर की तिथियों को बदलने की तरह। वे डीएसटी को अपनाए जाने को छोड़ना पसंद करते हैं। वे सीमाओं को बदलने, अपने समय क्षेत्र को फिर से परिभाषित करना पसंद करते हैं। वे कभी-कभी 15 मिनट की तरह अपनी ऑफसेट-यूटीसी को फिर से परिभाषित करना पसंद करते हैं। और वे शायद ही कभी अग्रिम नोटिस देते हैं, ऐसे बदलावों को एक महीने या दो चेतावनी के साथ कम करते हैं।

तो अगले वर्ष या छह महीने में मेडिकल चेक-अप नियुक्ति करने के लिए, समय क्षेत्र परिभाषा की भविष्यवाणी नहीं की जा सकती है। इसलिए यदि आप 9 बजे की नियुक्ति चाहते हैं, तो आपको के डेटाबेस कॉलम में दर्ज LocalTime या LocalDateTime का उपयोग करना चाहिए। अन्यथा 9 बजे नियुक्ति, यदि ज़ोन किया गया जहां डीएसटी कटओवर स्थगित कर दिया गया है, तो 8 पूर्वाह्न या 10 बजे के रूप में दिखाई दे सकता है।

प्रोजेक्ट शेड्यूल उत्पन्न करते समय, आप ZonedDateTime ऑब्जेक्ट्स बनाने के लिए उन "स्थानीय" (अनजान) मानों पर एक समय क्षेत्र (ZoneId) लागू कर सकते हैं। लेकिन समय पर उन लोगों पर भरोसा न करें जब राजनेता क्षेत्र को बदलकर अपना अर्थ बर्बाद कर सकते हैं।

युक्ति: डीएसटी और समय क्षेत्रों में ये लगातार परिवर्तन का मतलब है कि आपको अपना समय क्षेत्र tzdata डेटा बेस अद्यतित रखना होगा। आपके होस्ट ओएस, आपके जेवीएम में और शायद आपके डेटाबेस सिस्टम जैसे पोस्टग्रेस में tzdata है। सभी तीनों को अक्सर अद्यतन किया जाना चाहिए। कभी-कभी ज़ोन पिछले साल तुर्की जैसे उन उत्पादों के नियोजित अद्यतन चक्रों की तुलना में तेजी से बदलते हैं, जो पिछले कुछ हफ्तों के नोटिस के साथ डीएसटी पर रहने का फैसला करते हैं। इसलिए आपको कभी-कभी उन tzdata फ़ाइलों को मैन्युअल रूप से अपडेट करने की आवश्यकता हो सकती है। ओरेकल अपने जावा कार्यान्वयन के tzdata को अद्यतन करने के लिए एक उपकरण प्रदान करता है।

सटीक क्षणों को संभालने में सामान्य सर्वोत्तम अभ्यास उन्हें यूटीसी में ट्रैक करना है। केवल एक समय क्षेत्र लागू करें जहां आवश्यक हो जैसे उपयोगकर्ता को प्रस्तुति में जहां वे अपने स्वयं के संवहनी समय क्षेत्र में मूल्यों को देखने की अपेक्षा करते हैं। जावा.टाइम में, Instant कक्षा समयरेखा में एक पल का प्रतिनिधित्व करती है। यूटीसी में नैनोसेकंड के संकल्प के साथ।

Instant instant = Instant.now() ; // Current moment on the timeline in UTC. 
ZonedDateTime zdt = instant.atZone(z) ; // Assign a time zone to view the same moment through the lens of a particular region’s wall-clock time. 
Instant instant = zdt.toInstant(); // revert back to UTC, stripping away the time zone. But still the same moment in the timeline. 

वैसे, जेडीबीसी 4.2 और बाद में अनुपालन करने वाले ड्राइवर सीधे जावा के साथ सौदा कर सकते हैं।समय प्रकार के माध्यम से:

  • PreparedStatement::setObject
  • ResultSet::getObject

ऐसे java.util.Date और java.sql.Timestamp जब भी संभव हो के रूप में करने से बचें वर्ष विरासत डेटा प्रकार। वे खराब डिजाइन, भ्रमित, और दोषपूर्ण हैं।

समझ लें कि इन चार के सभी यूटीसी में समय रेखा पर एक पल का निरूपण कर रहे हैं:

  • आधुनिक
    • java.time.Instant
    • के साथ एक ZoneOffset.UTC
  • की भरपाई सौंपा java.time.OffsetDateTime
  • विरासत
    • java.util.Date
    • java.sql.Timestamp

आप एक तिथि-केवल मूल्य चाहते हैं समय के दिन और समय क्षेत्र के बिना बिना, java.time.LocalDate का उपयोग करें। इस वर्ग के सप्लायर java.sql.Date

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

+0

मैं कथन के साथ बहुत सहमत हूं कि एक पल यूटीसी में संग्रहीत किया जाना चाहिए और उपयोगकर्ता को प्रदर्शित करते समय केवल ज़ोन किया जाना चाहिए। –

+0

मुझे उम्मीद है कि मेरी 8 साल की बेटी (जो दावा करती है कि सांता असली नहीं है) इसे कुछ समय पढ़ना पड़ता है। न केवल एक महान जवाब, लेकिन जब तक मुझे "यही कारण है कि elves .." :) – NealeU

+0

टाइमज़ोन खूबसूरती से समझाया गया। उपरोक्त, धन्यवाद :-) –

-4

नई तिथि API का हिस्सा वे तिथियों के प्रकारों को विभाजित करते हैं। सही वर्ग है कि समय-क्षेत्रों में शामिल हैं ZonedDateTime

// Get the current date and time 
     ZonedDateTime date1 = ZonedDateTime.parse("2007-12-03T10:15:30+05:30[Asia/Karachi]"); 
     System.out.println("date1: " + date1); 

     ZonedDateTime zonedDateTime = ZonedDateTime.now(); 
     System.out.println("Zoned Date Time: " + zonedDateTime); 

     ZoneId id = ZoneId.of("Europe/Paris"); 
     System.out.println("ZoneId: " + id); 

     ZoneId currentZone = ZoneId.systemDefault(); 
     System.out.println("CurrentZone: " + currentZone); 

प्रिंटों है:

date1: 2007-12-03T10:15:30+05:00[Asia/Karachi] 
Zoned Date Time: 2017-04-18T11:36:09.126-04:00[America/New_York] 
ZoneId: Europe/Paris 
CurrentZone: America/New_York 
+0

मुझे 'ZonedDateTime' कक्षा के बारे में पता है। मेरा प्रश्न यूटीसी में डेटाबेस में दिनांक और डेटाटाइम संग्रहीत करने के लिए 'स्थानीयडेट' और 'लोकलडेट टाइम' कक्षाओं का उपयोग करने के बारे में अधिक है। – adi

+0

फिर आप डेटफॉर्मर –

+0

के साथ तत्काल संभावित रूप से उपयोग करना चाहेंगे, फिर से प्रश्न पढ़ने के लिए धन्यवाद। क्या आप अपना उत्तर अपडेट कर सकते हैं ताकि वह वास्तव में पूछे गए प्रश्न का उत्तर दे रहा हो? – adi

6

या मुझे जावा 8 के इंस्टेंट का उपयोग करना चाहिए? यदि इंस्टेंट का उपयोग करते हैं, तो होगा बिना समय के केवल तारीख भाग को स्टोर करने की संभावना?

तत्काल अधिकांश परिचालनों के लिए उपयुक्त होना चाहिए।

pom.xml को hibernate-java8 जोड़े जावा 8 समय एपीआई का समर्थन करने के:

<dependency> 
    <groupId>org.hibernate</groupId> 
    <artifactId>hibernate-java8</artifactId> 
    <version>${version.hibernate}</version> 
</dependency> 

तो फिर तुम LocalDate या LocalDateTime या हाइबरनेट इकाई क्षेत्रों के लिए Instant उपयोग कर सकते हैं। आपको @Temporal(TemporalType.TIMESTAMP) को हटाने की आवश्यकता है।

मेरे आवश्यकता डेटाबेस में सभी तिथियों यूटीसी समय क्षेत्र में & तिथि-समय स्टोर करने के लिए है। मैं अपने हाइबरनेट इकाइयों में जावा 8 के लोकलडेट & लोकलडेट टाइम का उपयोग कर रहा हूं।

क्या यह सही है कि स्थानीय दिनांक & स्थानीयडेटाइम के पास टाइमज़ोन उनके साथ जुड़ा हुआ नहीं है?

आप एक configurational कोड में कहीं डिफ़ॉल्ट JVM समय क्षेत्र सेट कर सकते हैं:

@PostConstruct 
void setUTCTimezone() { 
    TimeZone.setDefault(TimeZone.getTimeZone("UTC")); 
} 

तो फिर आप अपने कोड में UTC समय से संचालित की जाती है।

जावा का उपयोग करने के डीटीओ में 8 प्रकार की तारीख, आप Jsr310JpaConverters जोड़ने की जरूरत:

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-data-jpa</artifactId> 
</dependency> 

और:

@EntityScan(basePackageClasses = { Application.class, Jsr310JpaConverters.class }) 
SpringBootApplication 
public class Application { … } 

अधिक विकल्प: