PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

जावा का उपयोग करके PostgreSQL में समय संग्रहीत करने का सबसे अनुशंसित तरीका क्या है?

PostgreSQL में दिनांक और समय डेटा संग्रहीत करने की कोई भी रणनीति, IMO, इन दो बिंदुओं पर निर्भर होनी चाहिए:

  • आपका समाधान कभी नहीं होना चाहिए सर्वर या क्लाइंट टाइमज़ोन सेटिंग पर निर्भर करता है।
  • वर्तमान में, PostgreSQL (अधिकांश डेटाबेस के रूप में) में पूर्ण स्टोर करने के लिए डेटाटाइप नहीं है समय क्षेत्र के साथ दिनांक और समय। इसलिए, आपको Instant . के बीच निर्णय लेने की आवश्यकता है या एक LocalDateTime डेटाटाइप।

मेरी रेसिपी इस प्रकार है।

यदि आप भौतिक तत्काल . रिकॉर्ड करना चाहते हैं जब कोई विशेष घटना हुई, (एक सच्चा "टाइमस्टैम्प " , आम तौर पर कुछ निर्माण/संशोधन/हटाने की घटना), फिर उपयोग करें:

  • जावा:Instant (जावा 8 या जोडाटाइम)।
  • JDBC:java.sql.Timestamp
  • पोस्टग्रेएसक्यूएल:TIMESTAMP WITH TIMEZONE (TIMESTAMPTZ )

(PostgreSQL के अजीबोगरीब डेटाटाइप WITH TIMEZONE . को अनुमति न दें /WITHOUT TIMEZONE आपको भ्रमित करते हैं:उनमें से कोई भी वास्तव में समय क्षेत्र संग्रहीत नहीं करता है)

कुछ बॉयलरप्लेट कोड:निम्नलिखित मानते हैं कि ps एक PreparedStatement है , rs एक ResultSet और tzUTC एक स्थिर Calendar है UTC . के अनुरूप वस्तु समयक्षेत्र।

public static final Calendar tzUTC = Calendar.getInstance(TimeZone.getTimeZone("UTC"));  

Instant लिखें डेटाबेस के लिए TIMESTAMPTZ :

Instant instant = ...;
Timestamp ts = instant != null ? Timestamp.from(instant) : null;
ps.setTimestamp(col, ts, tzUTC);   // column is TIMESTAMPTZ!

पढ़ें Instant डेटाबेस से TIMESTAMPTZ :

Timestamp ts = rs.getTimestamp(col,tzUTC); // column is TIMESTAMPTZ
Instant inst = ts !=null ? ts.toInstant() : null;

यह सुरक्षित रूप से काम करता है यदि आपका पीजी प्रकार TIMESTAMPTZ . है (उस स्थिति में, calendarUTC उस कोड में कोई प्रभाव नहीं पड़ता है; लेकिन यह हमेशा सलाह दी जाती है कि डिफ़ॉल्ट टाइमज़ोन पर निर्भर न रहें)। "सुरक्षित रूप से" का अर्थ है कि परिणाम सर्वर या डेटाबेस टाइमज़ोन पर निर्भर नहीं होगा , या टाइमज़ोन जानकारी:ऑपरेशन पूरी तरह से प्रतिवर्ती है, और टाइमज़ोन सेटिंग्स के साथ जो कुछ भी होता है, आपको हमेशा वही "तत्काल समय" मिलेगा जो आपको मूल रूप से जावा की तरफ था।

यदि, टाइमस्टैम्प (भौतिक समयरेखा पर एक झटपट) के बजाय, आप एक "सिविल" स्थानीय दिनांक-समय के साथ काम कर रहे हैं (अर्थात, फ़ील्ड का सेट {year-month-day hour:min:sec(:msecs)} ), आप उपयोग करेंगे:

  • जावा:LocalDateTime (जावा 8 या जोडाटाइम)।
  • JDBC:java.sql.Timestamp
  • पोस्टग्रेएसक्यूएल:TIMESTAMP WITHOUT TIMEZONE (TIMESTAMP )

पढ़ें LocalDateTime डेटाबेस से TIMESTAMP :

Timestamp ts = rs.getTimestamp(col, tzUTC); //
LocalDateTime localDt = null;
if( ts != null ) 
    localDt =  LocalDateTime.ofInstant(Instant.ofEpochMilli(ts.getTime()), ZoneOffset.UTC);

LocalDateTime लिखें डेटाबेस के लिए TIMESTAMP :

  Timestamp ts = null;
  if( localDt != null)    
      ts = new Timestamp(localDt.toInstant(ZoneOffset.UTC).toEpochMilli()), tzUTC);
  ps.setTimestamp(colNum,ts, tzUTC); 

फिर से, यह रणनीति सुरक्षित है और आप चैन की नींद सो सकते हैं:अगर आपने 2011-10-30 23:59:30 स्टोर किया है , आप उन सटीक क्षेत्रों (घंटे =23, मिनट =59 ... आदि) को हमेशा पुनः प्राप्त करेंगे, चाहे कुछ भी हो - भले ही कल आपके पोस्टग्रेस्क्ल सर्वर (या क्लाइंट) का समय क्षेत्र बदल जाए, या आपका जेवीएम या आपका ओएस टाइमज़ोन, या यदि आपका देश अपने डीएसटी नियमों आदि को संशोधित करता है।

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. IntegrityError:अद्वितीय बाधा और अशक्त उल्लंघनों के बीच अंतर करें

  2. PostgreSQL 13 का अवलोकन libpq sslpassword कनेक्शन पैरामीटर

  3. Django:पुनर्स्थापित करने के बाद डेटाबेस तक पहुंचने का प्रयास करते समय अनुमति अस्वीकार कर दी गई (माइग्रेशन)

  4. PostgreSQL UNIQUE बाधा को कैसे लागू करता है/यह किस प्रकार की अनुक्रमणिका का उपयोग करता है?

  5. FATAL:उपयोगकर्ता पोस्टग्रेज के लिए पासवर्ड प्रमाणीकरण विफल रहा (pgAdmin 4 के साथ postgresql 11)