JavaTzone को GMT / UTC के रूप में बल दें


95

मुझे मशीन पर टाइमजोन सेट किए बिना, जीएमटी / यूटीसी को किसी भी समय संबंधित संचालन को बाध्य करने की आवश्यकता है। कोड में ऐसा करने का कोई सुविधाजनक तरीका?

स्पष्ट करने के लिए, मैं सभी कार्यों के लिए DB सर्वर समय का उपयोग कर रहा हूं, लेकिन यह स्थानीय समयक्षेत्र के अनुसार स्वरूपित है।

धन्यवाद!


वास्तव में, उनकी समस्या मेरी एक सबसेट है, लेकिन मुझे एक समाधान मिला।
SyBer

डुप्लिकेट प्रश्न को देखें, और "Joda" और "DateTimeZone" खोजें।
तुलसी बोर्क

जवाबों:


124

ओपी ने इस सवाल का जवाब दिया कि चल रहे जेवीएम के एकल उदाहरण के लिए डिफ़ॉल्ट टाइमज़ोन को बदलने के लिए, user.timezoneसिस्टम गुण सेट करें :

java -Duser.timezone=GMT ... <main-class>

यदि आपको किसी डेटाबेस से दिनांक / समय / टाइमस्टैम्प ऑब्जेक्ट प्राप्त करते समय विशिष्ट समय क्षेत्र निर्धारित करने की आवश्यकता होती है, तो ऑब्जेक्ट लेने ResultSetवाले getXXXतरीकों के दूसरे रूप का उपयोग करें Calendar:

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
ResultSet rs = ...;
while (rs.next()) {
    Date dateValue = rs.getDate("DateColumn", tzCal);
    // Other fields and calculations
}

या, तैयारी की तारीख में तारीख तय करना:

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
PreparedStatement ps = conn.createPreparedStatement("update ...");
ps.setDate("DateColumn", dateValue, tzCal);
// Other assignments
ps.executeUpdate();

यह सुनिश्चित करेगा कि डेटाबेस में संग्रहीत मूल्य संगत है जब डेटाबेस कॉलम टाइमजोन की जानकारी नहीं रखता है।

java.util.Dateऔर java.sql.Dateकक्षाओं यूटीसी में वास्तविक समय (मिलीसेकंड) की दुकान। किसी अन्य टाइमज़ोन के आउटपुट पर इन्हें प्रारूपित करने के लिए, उपयोग करें SimpleDateFormat। आप किसी कैलेंडर ऑब्जेक्ट का उपयोग करके समयक्षेत्र को भी संबद्ध कर सकते हैं:

TimeZone tz = TimeZone.getTimeZone("<local-time-zone>");
//...
Date dateValue = rs.getDate("DateColumn");
Calendar calValue = Calendar.getInstance(tz);
calValue.setTime(dateValue);

उपयोगी संदर्भ

https://docs.oracle.com/javase/9/troubleshoot/time-zone-settings-jre.htm#JSTGD377

https://confluence.atlassian.com/kb/setting-the-timezone-for-the-java-environment-841187402.html


संपूर्ण JVM के लिए समयक्षेत्र निर्धारित करने के बारे में एक बात ध्यान देने योग्य है कि यह सब कुछ प्रभावित करता है, जिसमें लॉगिंग जैसी चीजें शामिल हैं। यदि वांछित प्रभाव है तो बस कुछ ध्यान में रखना है।
हरमन हंस

हां, यह ठीक है। उल्लेख करने के लिए सिर्फ एक बिंदु, कि मैं वास्तव में user.timezone सीधे कोड में सेट करता हूं, बल्कि -D पैरामीटर के माध्यम से।
SyBer

6
@SyBer: वह काम करता है, लेकिन TimeZone.getDefault () विधि को कॉल करने से पहले आपको यह सुनिश्चित करना होगा कि आप इसे सेट करें। यदि नहीं तो आपको कुछ भ्रम होगा क्योंकि पहले निष्पादन के बाद डिफ़ॉल्ट को कैश किया जाता है। इसका मतलब यह भी है कि यह एक समस्या हो सकती है यदि आप एक एपीआई / लाइब्रेरी के अंदर ऐसा करते हैं (सादे दृश्य से छिपा हुआ है) - जो आप कर रहे हैं उसका भारी दस्तावेज करना सुनिश्चित करें।
केविन ब्रॉक

23

इसके अलावा अगर आप JVM टाइमजोन को इस तरह सेट कर सकते हैं

System.setProperty("user.timezone", "EST");

या -Duser.timezone=GMTजेवीएम में आता है।


System.setProperty("user.timezone" ...)काम नहीं करता है।
विल्मॉल

13

मुझे विंडोज 2003 सर्वर के लिए जेवीएम टाइमज़ोन सेट करना पड़ा क्योंकि यह हमेशा नई तारीख के लिए जीएमटी लौटाता था ();

-Duser.timezone=America/Los_Angeles

या आपका उपयुक्त समय क्षेत्र। समय क्षेत्र की सूची खोजना थोड़ा चुनौतीपूर्ण भी साबित हुआ ...

यहाँ दो सूची हैं;

http://wrapper.tanukisoftware.com/doc/english/prop-timezone.html

http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Frzatz%2F51%2Fadmin%2Freftz.htm


9

आप TimeZone.setDefault () का उपयोग करके समयक्षेत्र बदल सकते हैं :

TimeZone.setDefault(TimeZone.getTimeZone("GMT"))

कोई अपराध नहीं है, लेकिन अस्थायी रूप से एक वैश्विक स्थिर राज्य को संशोधित करना बहुत बुरा विचार लगता है ...
जी डेमीकी

आप कर सकते हैं, लेकिन आपको नहीं करना चाहिए। यह असाधारण रूप से बुरी सलाह है। पूरे JVM का समय बदल गया है।
स्कॉट

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

बिलकुल नहीं। यदि आप अपना पूरा सिस्टम UTC (एक बहुत अच्छा विचार) चाहते हैं, तो UTC को सिस्टम टाइमज़ोन सेट करें और जावा टाइमज़ोन को अकेला छोड़ दें।
स्कूट

3
सिवाय अगर आपके पास विभिन्न आवश्यकताओं के साथ कई जेवीएम हैं। हम हमेशा के लिए बहस कर सकते हैं लेकिन हर मामला अद्वितीय है: कभी-कभी आपको पूरे सिस्टम का टाइमज़ोन सेट करने की आवश्यकता होती है, कभी-कभी आप केवल एक जेवीएम सेट करते हैं। आइए खुश रहें कि आज की प्रणालियाँ इतनी लचीली हैं कि हम दोनों
or

8

मेरे लिए, बस जल्दी SimpleDateFormat,

  private static final SimpleDateFormat GMT = new SimpleDateFormat("yyyy-MM-dd");
  private static final SimpleDateFormat SYD = new SimpleDateFormat("yyyy-MM-dd");
  static {
      GMT.setTimeZone(TimeZone.getTimeZone("GMT"));
    SYD.setTimeZone(TimeZone.getTimeZone("Australia/Sydney"));
  }

फिर अलग-अलग टाइमज़ोन के साथ तारीख को प्रारूपित करें।


6

मैं DB से कच्चे रूप (लंबे टाइमस्टैम्प या जावा की तारीख) के समय को पुनः प्राप्त करूँगा, और फिर इसे प्रारूपित करने के लिए SimpleDateFormat का उपयोग कर सकता हूं या इसे हेरफेर करने के लिए कैलेंडर। दोनों ही मामलों में आपको उपयोग करने से पहले वस्तुओं का समय क्षेत्र निर्धारित करना चाहिए।

देखें SimpleDateFormat.setTimeZone(..)और Calendar.setTimeZone(..)विवरण के लिए


6

tl; डॉ

String sql = "SELECT CURRENT_TIMESTAMP ;

OffsetDateTime odt = myResultSet.getObject( 1 , OffsetDateTime.class ) ;

डिफ़ॉल्ट समय क्षेत्र के लिए होस्ट OS या JVM के आधार पर बचें

मैं आपको स्पष्ट रूप से वांछित / अपेक्षित समय क्षेत्र बताने के लिए अपना सारा कोड लिखने की सलाह देता हूं। आपको JVM के वर्तमान डिफ़ॉल्ट समय क्षेत्र पर निर्भर होने की आवश्यकता नहीं है। और ध्यान रखें कि JVM का वर्तमान डिफ़ॉल्ट समय क्षेत्र किसी भी एप्लिकेशन कॉलिंग के किसी भी थ्रेड में किसी भी कोड के साथ, रनटाइम के दौरान किसी भी क्षण बदल सकता है TimeZone.setDefault। ऐसी कॉल उस JVM के भीतर सभी ऐप्स को तुरंत प्रभावित करती है।

java.time

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

जेएसआर 310 में परिभाषित java.time कक्षाओं द्वारा विरासत की तारीखों के समय को दबा दिया गया है ।

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

मुझे जीएमटी / यूटीसी को किसी भी समय संबंधित संचालन को बाध्य करने की आवश्यकता है

शून्य घंटे-मिनट-सेकंड की ऑफसेट के लिए, निरंतर का उपयोग करें ZoneOffset.UTC

Instant

UTC में वर्तमान क्षण को पकड़ने के लिए, a का उपयोग करें Instant। यह वर्ग यूटीसी में एक क्षण का प्रतिनिधित्व करता है, हमेशा यूटीसी में परिभाषा के अनुसार।

Instant instant = Instant.now() ;  // Capture current moment in UTC.

ZonedDateTime

किसी विशेष क्षेत्र के लोगों द्वारा उपयोग किए जाने वाले दीवार-घड़ी समय के माध्यम से उसी क्षण को देखने के लिए, एक समय क्षेत्र में समायोजित करें। एक ही पल, समय रेखा पर एक ही बिंदु, अलग-अलग दीवार-घड़ी का समय।

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

डेटाबेस

आप एक डेटाबेस का उल्लेख करते हैं।

डेटाबेस से एक पल को पुनः प्राप्त करने के लिए, आपका कॉलम SQL-मानक के समान डेटा प्रकार का होना चाहिए TIMESTAMP WITH TIME ZONE। एक स्ट्रिंग के बजाय एक वस्तु को पुनः प्राप्त करें। JDBC 4.2 और बाद में, हम डेटाबेस के साथ java.time ऑब्जेक्ट्स का आदान-प्रदान कर सकते हैं । OffsetDateTime, JDBC के लिए आवश्यक है, जबकि Instantऔर ZonedDateTimeवैकल्पिक हैं।

OffsetDateTime odt = myResultSet.getObject(  , OffsetDateTime.class ) ;

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

  • एक निकालें Instant: odt.toInstant()
  • दिए गए ऑफ़सेट से शून्य की ऑफ़सेट पर समायोजित करें: ऑफ़सेटडाइट टाइम odtUtc = odt.withOffsetSameInstant (ZoneOffset.UTC); `।

जावा में दिनांक-समय प्रकार की तालिका (दोनों विरासत और आधुनिक) और मानक एसक्यूएल में


जावा के बारे में

Java.time ढांचे जावा 8 और बाद में बनाया गया है। इन कक्षाओं परेशानी वर्ष प्रतिस्थापित विरासत जैसे तिथि-समय कक्षाएं java.util.Date, Calendar, और SimpleDateFormat

अधिक जानने के लिए, Oracle ट्यूटोरियल देखें । और कई उदाहरणों और स्पष्टीकरणों के लिए ढेर अतिप्रवाह खोजें। विशिष्टता JSR 310 है

Joda समय परियोजना, अब में रखरखाव मोड , प्रवास करने की सलाह देता java.time कक्षाएं।

आप अपने डेटाबेस से सीधे java.time वस्तुओं का आदान-प्रदान कर सकते हैं । JDBC 4.2 या उसके बाद के JDBC ड्राइवर का अनुपालन करें । तार की कोई जरूरत नहीं, कक्षाओं की कोई जरूरत नहीं ।java.sql.*

Java.time कक्षाएं कहाँ से प्राप्त करें?


1

क्लाइंट / सर्वर की एक जोड़ी बनाएं, ताकि निष्पादन के बाद, क्लाइंट सर्वर सही समय और तारीख भेजता है। फिर, क्लाइंट सर्वर pm GMT से पूछता है और सर्वर उत्तर सही वापस भेजता है।


1

सिस्टम प्रॉपर्टी का उपयोग करें:

-Duser.timezone=UTC

5
क्यों एक का उपयोग करना चाहिए? कृपया अपने उत्तर में कुछ स्पष्टीकरण जोड़ें, ताकि अन्य लोग इससे सीख सकें
निको हेस

1

अपने समयक्षेत्र को रीसेट करने के लिए MySQL में इस लाइन को निष्पादित करें:

SET @@global.time_zone = '+00:00';

0

वाह। मुझे पता है कि यह एक प्राचीन धागा है, लेकिन सभी मैं कह सकता हूं कि किसी भी उपयोगकर्ता-स्तरीय कोड में TimeZone.setDefault () को कॉल न करें। यह हमेशा पूरे JVM के लिए Timezone सेट करता है और लगभग हमेशा एक बहुत बुरा विचार है। जावा 8 में joda.time लाइब्रेरी या नए DateTime क्लास का उपयोग करना सीखें जो कि joda.time लाइब्रेरी से काफी मिलता-जुलता है।


-6

यदि आप GMT का समय केवल intiger के साथ प्राप्त करना चाहते हैं: var currentTime = new Date (); var currentYear = '2010' var currentMonth = 10; var currentDay = '30 'var currentHours = '20' var currentMinutes = '20 'var currentSeconds = '00' var currentMilliseconds = '00 '

currentTime.setFullYear(currentYear);
currentTime.setMonth((currentMonth-1)); //0is January
currentTime.setDate(currentDay);  
currentTime.setHours(currentHours);
currentTime.setMinutes(currentMinutes);
currentTime.setSeconds(currentSeconds);
currentTime.setMilliseconds(currentMilliseconds);

var currentTimezone = currentTime.getTimezoneOffset();
currentTimezone = (currentTimezone/60) * -1;
var gmt ="";
if (currentTimezone !== 0) {
  gmt += currentTimezone > 0 ? ' +' : ' ';
  gmt += currentTimezone;
}
alert(gmt)

5
मेरे लिए जावास्क्रिप्ट (= जावा) जैसा दिखता है।
फिल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.