आईएसओ 8601 और ECMAScript - गलत मानकों का सिरदर्द

हम यहां थर्ड-पार्टी सिस्टम के साथ कुछ एकीकरण सेवा विकसित कर रहे हैं। यह सेवा स्वयं Node.js. पर चलती है और सब कुछ ठीक हो जाएगा, लेकिन कचरा संग्रह के दौरान केवल सर्वर की अनुपलब्धता ने तीसरे पक्ष के सिस्टम को बहुत परेशान किया।

नए साल की पूर्व संध्या पर, सर्वर को एक उपहार देने का फैसला किया गया था - Node.js को 0.4.8 संस्करण से 0.6.6 पर अपग्रेड करें। कई संगठनात्मक कारणों से जो मैं वास्तव में यहां चर्चा नहीं करना चाहता हूं, अपडेट तुरंत मुकाबला प्रणाली और यहां तक ​​कि प्रतिगमन परीक्षण के बिना भी किया गया था।

क्या इस स्थिति में कुछ गलत हो सकता है?

अपडेट किया गया। हम आगे काम करते हैं। यह अचानक पता चलता है कि तृतीय-पक्ष प्रणाली द्वारा प्रेषित संदेशों में, समय 4 घंटे आगे स्थानांतरित किया जाता है। इस तरह की पारी के व्यावसायिक परिणामों के बारे में बात करने की आवश्यकता नहीं है।

सोचना शुरू करो। एक परिकल्पना है कि अगर सब कुछ पहले काम करता था, लेकिन Node.js अद्यतन के साथ यह अचानक बंद हो गया, इसका मतलब है कि मामला इसमें है या v8 में है। यह मैं नहीं कह सकता इस तरह के एक जाम और हम नोटिस करने के लिए पहली बार थे - यकीन है कि यह हमारे व्यवस्थापक खराब कर दिया है। जाहिर है, मैं कहता हूं, वह सर्वर पर टाइम ज़ोन की सेटिंग्स के साथ कुछ गलत है। हमने सभी संभावित नुक्कड़ और सारस में देखा - नहीं, सब कुछ साफ है।

अंतिम, सबसे अविश्वसनीय परिकल्पना बनी हुई है - आईएसओ 8601 प्रारूप में समय का विश्लेषण टूट गया है। यह इस प्रारूप में है कि तृतीय-पक्ष प्रणाली संदेशों में समय भेजती है। ऐसा लगेगा कि यहां क्या तोड़ा जा सकता है। यहाँ स्थानीय समय आता है: "2011-12-30T22: 00: 00"। हम जल्दी से सर्वर में देखते हैं:

 > var d = नई तिथि ('2011-12-30T22: 00: 00')
 अपरिभाषित
 > d
 शुक्र, 30 दिसंबर 2011 22:00:00 जीएमटी
 > d.getHours ()
 2

हे भगवान। सर्वर स्पष्ट रूप से GMT में रहता है। अन्यथा नहीं, पहले से ही उत्सर्जित। हम जाँच करते हैं:

 > var d = नई तिथि ('2011-12-30T22: 00: 00Z')
 अपरिभाषित
 > d
 शुक्र, 30 दिसंबर 2011 22:00:00 जीएमटी
 > d.getHours ()
 2

दोनों मामलों में, चाहे वह समय स्थानीय रूप से इंगित किया गया हो या GMT, इसे GMT माना जाता है। हम देखते हैं कि क्रोम इस पर क्या कहेगा:

 > var d = नई तिथि ('2011-12-30T22: 00: 00')
 अपरिभाषित
 > d.toString ()
 "सैट 31 दिसंबर 2011 02:00:00 GMT + 0400 (MSK)"
 > d.getHours ()
 2

लेकिन यह पहले से ही अप्रिय है। क्रोम - वर्कस्टेशन पर। और समय क्षेत्र के साथ सब कुछ क्रम में है।

जबकि डेवलपर ने मुझे इस सवाल के साथ ताना मारा कि "हम Google पर बग को कब पोस्ट करेंगे?" मैंने मानक का वर्णन पढ़ा। एक आधिकारिक दस्तावेज़ के लिए 130 फ़्रैंक नहीं है, इसलिए, हम विकिपीडिया का अध्ययन करते हैं :
यदि कोई UTC संबंध जानकारी समय प्रतिनिधित्व के साथ नहीं दी जाती है, तो समय को स्थानीय समय माना जाता है

आगे की खुदाई।

 var d = नई तिथि ('2011-12-30T22: 00: 00')
 अपरिभाषित
 घ।  getTimezoneOffset () / 60
 -4

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

 var d = नई तिथि ('2011-12-30T22: 00: 00')
 अपरिभाषित
 d.getUTCHours ()
 18
 d.getHours ()
 22

Windows के अंतर्गत Chrome में समान चेकिंग:

 var d = नई तिथि ('2011-12-30T22: 00: 00')
 अपरिभाषित
 d.getUTCHours ()
 22
 d.getHours ()
 2

वाह! क्या गूगल वास्तव में एक जाम है? फिर से एक बग रिपोर्ट लिखने का प्रस्ताव है। रचना करना अभी भी बहुत आलसी है, इसलिए मैं मैनुअल पढ़ना शुरू कर रहा हूं।

मोज़िला डेवलपर नेटवर्क (MDN)। Date.parse विधि का विवरण:
यदि आप एक समय क्षेत्र निर्दिष्ट नहीं करते हैं, तो स्थानीय समय क्षेत्र मान लिया जाता है

यहां, समय मानक के अनुसार हल किया गया है, इसलिए फ़ायरफ़ॉक्स इसे सही कर रहा है।

V8 पर कोई स्वतंत्र प्रलेखन नहीं है, लेकिन ECMAscript का एक लिंक है। विनिर्देश संस्करण 5.1 डाउनलोड करें , पृष्ठ 181 पर हम पढ़ते हैं:
अनुपस्थित समय क्षेत्र ऑफ़सेट का मान "Z" है।

वाह! एक तृतीय-पक्ष प्रणाली हमें आईएसओ मानक के अनुसार स्थानीय समय भेजती है, और हमारा सर्वर इसे GMT के रूप में व्याख्या करता है - ECMA मानक के अनुसार पूर्ण रूप से।

बस के मामले में, मैं MSDN पढ़ रहा हूँ - Microsoft ने लंबे समय से दावा किया है कि उनका जावास्क्रिप्ट मानक सबसे सही है, क्योंकि यह ECMA है। और यकीन के लिए:
यदि आप Z स्थिति में कोई मूल्य शामिल नहीं करते हैं, तो UTC समय का उपयोग किया जाता है।

रिपॉजिटरी के एक अध्ययन से पता चला है कि v8 व्यवहार का एक ही सुधार जून 2011 के अंत में संस्करण 8513 में किया गया था । हालांकि, जब मोज़िला को अपने हाथों में इसे ठीक करने के लिए कहा गया था , तो चर्चा ने आईएसओ और ईसीएमए 5.1 मानकों में अंतर को इंगित किया था। परिणामस्वरूप, एक मौका है। ECMA मानक के संस्करण 6 में, समय अभी भी सही ढंग से समझा जाएगा।

इस बीच, हमें कोड में बैसाखी जोड़ना था। यदि थर्ड-पार्टी सिस्टम से आने वाले समय में समय क्षेत्र का संकेत नहीं है, तो इसमें getTimezoneOffset जोड़ें। नए ECMA मानक जारी होने के बाद, जिसमें इस विसंगति को ठीक किया जाता है और v8 को इस मानक के अनुसार अद्यतन किया जाता है, हमें इसे ट्रैक करना होगा और बैसाखी को हटाना होगा।

PS वर्णित घटनाओं में मुख्य झटका zerodivisi0n habrayuzer द्वारा लिया गया था, जो दुर्भाग्य से, केवल-पढ़ने के अधिकार हैं। यदि किसी के पास पर्याप्त कर्म है (या जो कुछ भी वहां आवश्यक है) उसे और अधिक उन्नत स्थिति में रखने के लिए, हम दोनों बहुत आभारी होंगे। साथ ही वह खुद भी सवालों के जवाब दे सकेगा।

Source: https://habr.com/ru/post/In135565/


All Articles