2016-11-26 11 views
18

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

मुझे समस्या दिखाने के लिए यह सरल कार्यक्रम मिला है।

public static void main(String[] args) { 
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"); 
    Calendar calendar = Calendar.getInstance(); 

    System.out.println("**********Before 1945"); 
    calendar.set(1943, Calendar.APRIL, 12, 5, 34, 12); 
    System.out.println(format.format(calendar.getTime())); 
    System.out.println(calendar.getTime()); 

    System.out.println("**********After 1945"); 
    calendar.set(1946, Calendar.APRIL, 12, 5, 34, 12); 
    System.out.println(format.format(calendar.getTime())); 
    System.out.println(calendar.getTime()); 
} 

उत्पादन मैं हो रही है नीचे है: -

**********Before 1945 
1943-04-12 05:34:12+0630 
Mon Apr 12 05:34:12 IDT 1943 

**********After 1945 
1946-04-12 05:34:12+0530 
Fri Apr 12 05:34:12 IST 1946 

पहले एक के लिए, मैं यह +0630 और IDT के रूप में हो रही है, जबकि दूसरे के लिए, मैं +0530 और IST हो रही है जो अपेक्षित है।

संपादित करें: -

@Elliott Frisch जवाब को देखने के बाद मैं 1942 से पहले एक तारीख की कोशिश की: -

calendar.set(1915, Calendar.APRIL, 12, 5, 34, 12); 
System.out.println(format.format(calendar.getTime())); 
System.out.println(calendar.getTime()); 

उत्पादन: -

1915-04-12 05:34:12+0553 
Mon Apr 12 05:34:12 IST 1915 

यहां भी यह कहते हैं IST लेकिन दिखाता है +0553। यह +0530 नहीं होना चाहिए।

बस एक तुलना के लिए

, मैं जावास्क्रिप्ट में एक ही बात करने की कोशिश की: -

new Date("1946-04-12 05:34:12") //prints Fri Apr 12 1946 05:34:12 GMT+0530 (IST) 
new Date("1943-04-12 05:34:12") //prints Fri Apr 12 1943 05:34:12 GMT+0530 (IST) 
new Date("1915-04-12 05:34:12") //prints Mon Apr 12 1915 05:34:12 GMT+0530 (IST) 

कौन सा ठीक काम करता है। मैं जानना चाहता हूं कि जावा इससे क्यों प्रभावित होता है, और यदि यह ज्ञात समस्या है, तो के लिए संभावित कार्यवाही क्या है।

अग्रिम धन्यवाद।

+3

ईसीएमएस्क्रिप्ट 2016 से पहले, जावास्क्रिप्ट कार्यान्वयन से वर्तमान डेलाइट सेविंग नियमों को लागू करने की उम्मीद की गई थी जैसे कि उन्होंने हमेशा लागू किया था (यानी उन्होंने डेलाइट सेविंग स्टार्ट में ऐतिहासिक परिवर्तन लागू नहीं किए थे और विभिन्न भौगोलिक क्षेत्रों में विभिन्न अधिकार क्षेत्र द्वारा परिभाषित दिनांकों को रोक दिया था) देखें [* ES5 §15.9.1.8 *] (http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.8))। जबकि यह [* अब अनुशंसित *] है (http://ecma-international.org/ecma-262/7.0/index.html#sec-daylight-saving-time- समायोजन) IANA समय क्षेत्र डेटाबेस का उपयोग करने के लिए, कार्यान्वयन हैं (और शायद नहीं) की आवश्यकता नहीं है। – RobG

उत्तर

13

यह जावा (और जावास्क्रिप्ट से नहीं) की अपेक्षित व्यवहार की संभावना है।

ऊपर RobG द्वारा टिप्पणी द्वारा निहित, प्रोग्रामिंग भाषाएं ऐतिहासिक समय नियमों (जैसे डीएसटी और टाइमज़ोन ऑफ़सेट) का समर्थन कर सकती हैं या नहीं। आपके मामले में, ऐसा लगता है कि आपका जावा रनटाइम इसका समर्थन करता है, जबकि आपका जावास्क्रिप्ट रनटाइम नहीं करता है।

भारत के लिए ऐतिहासिक समय क्षेत्र और डीएसटी नियमों की एक सूची timeanddate.com पर पाई जा सकती है।सूची अपने जावा तारीखों के समय क्षेत्र ऑफसेट पुष्टि करता है:

  • 1941 तक: UTC + 5: 53: 20
  • 1941: UTC + 6: 30
  • 1942: UTC + 5: 30
  • 1943-1944: UTC + 6: 30
  • 1945 से: UTC + 5: |: 1915, 1943, 01 30

Wolfram के खिलाफ अपनी तिथियाँ जाँच हो रही है अल्फा आगे अपने जावा तारीख यूटीसी ऑफसेट की पुष्टि करता है

विकिपीडिया time in India बारे में अधिक जानकारी प्रदान करता है:

कलकत्ता समय आधिकारिक तौर पर या तो के रूप में निर्दिष्ट किया जा सकता है 1948

Calcutta time जब तक एक अलग समय क्षेत्र के रूप में बनाए रखा गया था UTC + 5: 54 या UTC + 5:53:20। उत्तरार्द्ध आपके कोड उदाहरण के अनुरूप है।

विकिपीडिया प्रविष्टि आगे सूचित करता है कि एक यूटीसी के ऑफसेट + 5 के साथ वर्तमान IST समय क्षेत्र: 30 1955.

pointed out by Elliott Frisch के रूप में जब तक भारत के सभी में पूर्ण प्रभाव में नहीं था और लिंक द्वारा की पुष्टि की timeanddate.com उपरोक्त, डीएसटी WWII के दौरान प्रभावी था। उसके जवाब देने के लिए अपनी टिप्पणी में, आप राज्य:

इस तरह से हम डेटाबेस में बचाने के लिए और अनुप्रयोगों में इसका इस्तेमाल करने की अपेक्षा की जाती है, या हम कुछ तरीके का उपयोग के लिए यह

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

10

war था। विकिपीडिया लिंक से, भारत ने 1 942-19 45 से विश्व युद्ध 2 के दौरान डीएसटी मनाया।

+0

अरे, उत्तर के लिए धन्यवाद, मैं जानना चाहता था कि जावा इससे क्यों प्रभावित होता है। कृपया मेरे अपडेट किए गए प्रश्न, * संपादन भाग * पर एक नज़र डालें। – Mritunjay

+0

अरे, मैं जानना चाहता था कि जिस तरह से हम डेटाबेस में सहेजना चाहते हैं और इसे अनुप्रयोगों में उपयोग करना चाहते हैं, या हम इसके लिए कुछ कामकाज का उपयोग करते हैं। अग्रिम में धन्यवाद। – Mritunjay

6

java.time

बचें जावा के जल्द से जल्द संस्करणों के साथ बंडल परेशानी पुराने तिथि-समय वर्गों का उपयोग करना। अब विरासत, java.time कक्षाओं द्वारा आपूर्ति की गई।

ZoneId z = ZoneId.of("Asia/Kolkata"); // "Asia/Calcutta" 
LocalTime lt = LocalTime.of(5 , 34 , 12); 

ZonedDateTime zdt1943 = ZonedDateTime.of(LocalDate.of(1943 , Month.APRIL , 12) , lt , z); 
ZonedDateTime zdt1945 = ZonedDateTime.of(LocalDate.of(1945 , Month.APRIL , 12) , lt , z); 
ZonedDateTime zdt1946 = ZonedDateTime.of(LocalDate.of(1946 , Month.APRIL , 12) , lt , z); 
ZonedDateTime zdt2016 = ZonedDateTime.of(LocalDate.of(2016 , Month.APRIL , 12) , lt , z); 

कंसोल पर डंप करें।

System.out.println("zdt1943: " + zdt1943); 
System.out.println("zdt1945: " + zdt1945); 
System.out.println("zdt1946: " + zdt1946); 
System.out.println("zdt2016: " + zdt2016); 

live code in IdeOne.com देखें।

रन करते समय। हम आपके प्रश्न में वर्णित वही व्यवहार देखते हैं, जिसमें offset-from-UTC युद्ध के दौरान साढ़े चार घंटे और साढ़े पांच घंटे बाद। हमें वही व्यवहार मिलता है चाहे Asia/Kolkata या Asia/Calcutta का उपयोग कर रहे हों। जावा.टाइम क्लासेस tzdata का उपयोग करते हैं, जिसे पहले ओल्सन डाटाबेस के नाम से जाना जाता था।

zdt1943: 1943-04-12T05: 34: 12 + 06: 30 [एशिया/कोलकाता]

zdt1945: 1945-04-12T05: 34: 12 + 06: 30 [एशिया/कोलकाता]

zdt1946: 1946-04-12T05: 34: 12 + 05: 30 [एशिया/कोलकाता]

zdt2016: 2016-04-12T05: 34: 12 + 05: 30 [एशिया/कोलकाता]

प्रश्न में ...

जब मैंने 1 9 45 से पहले साल की तारीख डाली, तो यह टाइमज़ोन बदलता है।

नहीं यह समय क्षेत्र बदलता है। नतीजे बताते हैं कि पिछले वर्षों में "5:34" को UTC से ढाई घंटे पहले परिभाषित किया गया था, जबकि बाद के वर्षों में परिभाषा यूटीसी से ढाई घंटे आगे हो गई थी। जैसे ही "5:34" का अर्थ गर्मियों में सिएटल में यूटीसी के पीछे आठ घंटे है, लेकिन सर्दियों में सात घंटे, Daylight Saving Time (DST) बकवास के कारण।

लेकिन मुझे संदेह है कि ये गलत मान हो सकते हैं; पढ़ते रहिये।

कलकत्ता

व्यवहार हम देख रहे हैं इस विकिपीडिया पृष्ठ, Time in Calcutta की मेरी पढ़ने मिलान करने के लिए प्रतीत नहीं होता है में समय। उस पृष्ठ में UTC+05:54 जैसे कि आधे घंटे के अलावा अजीब ऑफसेट का वर्णन किया गया है, जिसे हम अपने किसी भी संबंधित कोड नमूने में नहीं देख रहे हैं।

तो मुझे संदेह है कि tzdata में भारत के लिए यह ऐतिहासिक डेटा नहीं है। लेकिन सिर्फ इस लेजर का अनुमान; मैं कोई इतिहासकार नहीं हूं।

ऐतिहासिक मूल्यों

के लिए तिथि-समय प्रकार का प्रयोग न करें जब मैं भारत और tzdata में अपनी निपटने के इस ऐतिहासिक काल में समय के विवरण पता नहीं है, ऐसा लगता है कि हमारे तिथि-समय पुस्तकालयों में से कोई भी कर रहे हैं इन ऐतिहासिक बारीकियों को संभालना।

लेकिन हमें ऐसी हैंडलिंग की उम्मीद नहीं करनी चाहिए! पता है कि tzdatatime zones before 1970 का पूर्ण कवरेज का वादा करता है।

ऐतिहासिक दिनांक-समय मानों का जिक्र करते समय, मेरा सुझाव है कि आप किसी भी दिनांक-समय डेटा प्रकार की बजाय बस टेक्स्ट का उपयोग करें। डेटा प्रकार का उद्देश्य सत्यापन और गणना के लिए है। आप शायद ऐतिहासिक मूल्यों के लिए न तो कर रहे हैं। मैं कल्पना नहीं कर सकता कि आप 1 9 43 से चालान के दिनों की संख्या निर्धारित कर रहे हैं।

शायद आपको यह प्रश्न यह बताने के लिए अपना प्रश्न संपादित करना चाहिए कि आप इन ऐतिहासिक दिनांक-समय मानों को डेटाबेस में क्यों ठीक से संग्रहीत कर रहे हैं। यदि आप केवल इन मुद्दों का प्रयोग कर रहे थे और इन्हें ध्यान में रखते थे, तो जानते हैं कि आपको अतीत में (1 9 70 से पहले) और न ही भविष्य में सटीक दिनांक-समय पर संभालने की उम्मीद नहीं करनी चाहिए (कुछ हफ्तों के नोटिस के बाद राजनेता कभी-कभी अचानक समय क्षेत्र परिभाषा में बदलाव करते हैं) ।

उपशॉट: ऐतिहासिक दिनांक-समय मूल्यों को ठीक से संभालने का प्रयास विभिन्न मुद्दों से भरा हुआ है और मुझे व्यर्थ लगता है।

के लिए संभव समाधान नहीं है क्या यह

मैं किसी भी समय क्षेत्र के बिना आईएसओ 8601 प्रारूप में पाठ के रूप में "स्थानीय" तिथि-समय मानों का उपयोग कर सुझाव देते हैं।

1

मैं डेटाबेस में तारीखों के समतुल्य युग को रखने की अनुशंसा करता हूं। मेरा मानना ​​है कि, दिन की रोशनी बचत के बावजूद, अवधि का समय और तिथि वास्तविक का प्रतिनिधित्व करती है, चाहे वह आईडीटी या आईएसटी हो। मैं उदाहरण https://stackoverflow.com/a/6687502 का उपयोग करता हूं और सभी तिथियों को युग में परिवर्तित करता हूं और डीबी में स्टोर करता हूं। मैं उपयोगकर्ता के लिए भ्रम से बचने के लिए आईडीटी/आईएसटी संकेतक के साथ डाटाबेस से दिनांक समय प्रदर्शित करने के लिए तर्क को उलट दूंगा।

संबंधित मुद्दे