जेएस दुभाषिया लिखने के हाल के अनुभव के दौरान मैंने ईसीएमए / जेएस तिथियों के आंतरिक कामकाज के साथ बहुत कुश्ती की। इसलिए, मुझे लगता है कि मैं अपने 2 सेंट में फेंक दूंगा। उम्मीद है कि इस सामान को साझा करने से ब्राउज़रों के बीच मतभेदों के बारे में किसी भी प्रश्न में मदद मिलेगी कि वे तारीखों को कैसे संभालते हैं।
इनपुट साइड
सभी कार्यान्वयन अपने दिनांक मानों को आंतरिक रूप से 64-बिट संख्याओं के रूप में संग्रहीत करते हैं जो 1970-01-01 UTC के बाद मिलीसेकंड (ms) की संख्या का प्रतिनिधित्व करते हैं (GMT UTC जैसी ही बात है)। यह तिथि ECMAScript युग है जिसका उपयोग अन्य भाषाओं जैसे जावा और पॉसिक्स सिस्टम जैसे UNIX द्वारा भी किया जाता है। युग के बाद होने वाली तिथियां सकारात्मक संख्या हैं और पूर्व की तारीखें नकारात्मक हैं।
निम्नलिखित कोड की व्याख्या सभी वर्तमान ब्राउज़रों में एक ही तारीख के रूप में की जाती है, लेकिन स्थानीय समय-क्षेत्र ऑफसेट के साथ:
Date.parse('1/1/1970'); // 1 January, 1970
मेरे टाइमज़ोन में (ईएसटी, जो -05: 00 है), परिणाम 18000000 है, क्योंकि 5 घंटे में कितने एमएस हैं (यह दिन के बचत महीनों के दौरान केवल 4 घंटे हैं)। अलग-अलग समय क्षेत्रों में मूल्य अलग-अलग होगा। यह व्यवहार ECMA-262 में निर्दिष्ट है, इसलिए सभी ब्राउज़र इसे उसी तरह करते हैं।
हालांकि इनपुट स्ट्रिंग प्रारूपों में कुछ बदलाव है कि प्रमुख ब्राउज़र तारीखों के रूप में पार्स करेंगे, वे अनिवार्य रूप से उन्हें उसी तरह से व्याख्या करते हैं जहां समय क्षेत्र और दिन के उजाले की बचत का संबंध है, हालांकि पार्सिंग काफी हद तक कार्यान्वयन पर निर्भर है।
हालांकि, आईएसओ 8601 प्रारूप अलग है। यह ECMAScript 2015 (एड 6) में उल्लिखित केवल दो प्रारूपों में से एक है जिसे विशेष रूप से सभी कार्यान्वयनों द्वारा एक ही तरह से पार्स किया जाना चाहिए (अन्य Date.prototype.toString के लिए निर्दिष्ट प्रारूप है )।
लेकिन, यहां तक कि आईएसओ 8601 प्रारूप के तार के लिए, कुछ कार्यान्वयन गलत हो जाते हैं। यहाँ क्रोम और फ़ायरफ़ॉक्स का तुलनात्मक आउटपुट दिया गया है जब मूल रूप से आईएसओ 8601 प्रारूप स्ट्रिंग्स का उपयोग करके मेरी मशीन पर 1/1/1970 (युग) के लिए यह उत्तर लिखा गया था, जिसे सभी कार्यान्वयनों में समान मूल्य पर पार्स किया जाना चाहिए :
Date.parse('1970-01-01T00:00:00Z'); // Chrome: 0 FF: 0
Date.parse('1970-01-01T00:00:00-0500'); // Chrome: 18000000 FF: 18000000
Date.parse('1970-01-01T00:00:00'); // Chrome: 0 FF: 18000000
- पहले मामले में, "Z" विनिर्देशक इंगित करता है कि इनपुट यूटीसी समय में है इसलिए एपच से ऑफसेट नहीं है और परिणाम 0 है।
- दूसरे मामले में, "-0500" निर्दिष्ट इंगित करता है कि इनपुट GMT-05: 00 में है और दोनों ब्राउज़र इनपुट की व्याख्या -05: 00 टाइमज़ोन में करते हैं। इसका मतलब है कि यूटीसी मूल्य युग से ऑफसेट है, जिसका मतलब है कि तारीख के आंतरिक समय मूल्य में 18000000ms जोड़ना।
- तीसरा मामला, जहां कोई निर्दिष्ट नहीं है, मेजबान प्रणाली के लिए स्थानीय माना जाना चाहिए। एफएफ इनपुट को स्थानीय समय के रूप में सही ढंग से मानता है जबकि क्रोम इसे यूटीसी के रूप में मानता है, इसलिए विभिन्न समय मूल्यों का उत्पादन करता है। मेरे लिए यह संग्रहीत मूल्य में 5 घंटे का अंतर पैदा करता है, जो समस्याग्रस्त है। अलग-अलग ऑफसेट के साथ अन्य प्रणालियों को अलग-अलग परिणाम मिलेंगे।
यह अंतर 2020 के रूप में तय किया गया है, लेकिन आईएसओ 8601 प्रारूप स्ट्रिंग पार्स करते समय ब्राउज़र के बीच अन्य quirks मौजूद हैं।
लेकिन यह खराब हो जाता है। ईसीएमए -262 का एक प्रश्न यह है कि आईएसओ 8601 तारीख-केवल प्रारूप (YYYY-MM-DD) को UTC के रूप में पार्स किया जाना आवश्यक है, जबकि ISO 8601 को स्थानीय के रूप में पार्स करने की आवश्यकता है। यहां एफएफ से लंबे समय तक और लघु आईएसओ तिथि प्रारूपों के साथ आउटपुट है जिसमें कोई समय क्षेत्र निर्दिष्ट नहीं है।
Date.parse('1970-01-01T00:00:00'); // 18000000
Date.parse('1970-01-01'); // 0
इसलिए पहले को स्थानीय माना जाता है क्योंकि यह आईएसओ 8601 तारीख है और समय नहीं के साथ समय है, और दूसरा यूटीसी के रूप में पार्स किया गया है क्योंकि यह केवल आईएसओ 8601 तारीख है।
इसलिए, सीधे मूल प्रश्न का उत्तर देने के लिए, "YYYY-MM-DD"
ECMA-262 द्वारा UTC के रूप में व्याख्या की आवश्यकता होती है, जबकि अन्य की व्याख्या स्थानीय के रूप में की जाती है। इसीलिए:
यह समतुल्य परिणाम नहीं देता है:
console.log(new Date(Date.parse("Jul 8, 2005")).toString()); // Local
console.log(new Date(Date.parse("2005-07-08")).toString()); // UTC
यह करता है:
console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08T00:00:00")).toString());
नीचे की रेखा पार्सिंग डेट स्ट्रिंग्स के लिए है। केवल आईएसओ 8601 स्ट्रिंग जिसे आप सुरक्षित रूप से ब्राउज़रों में पार्स कर सकते हैं एक ऑफसेट (या तो एचएच: मिमी या "जेड") के साथ लंबा रूप है । यदि आप ऐसा करते हैं, तो आप स्थानीय और यूटीसी समय के बीच सुरक्षित रूप से आगे और पीछे जा सकते हैं।
यह ब्राउज़रों में काम करता है (IE9 के बाद):
console.log(new Date(Date.parse("2005-07-08T00:00:00Z")).toString());
अधिकांश वर्तमान ब्राउज़र अन्य इनपुट स्वरूपों के साथ समान रूप से व्यवहार करते हैं, जिनमें अक्सर इस्तेमाल किया जाने वाला '1/1/1970' (M / D / YYYY) और '1/1/1970 00:00:00 AM' (M / D / YYYY hh) शामिल हैं। : मिमी: एसएस एपी) प्रारूप। सभी ब्राउज़रों में स्थानीय प्रारूप के रूप में निम्नलिखित सभी स्वरूपों (अंतिम को छोड़कर) को माना जाता है। इस कोड का आउटपुट मेरे टाइमज़ोन के सभी ब्राउज़रों में समान है। आखिरी को मेजबान टाइमज़ोन की परवाह किए बिना -05: 00 के रूप में माना जाता है क्योंकि ऑफसेट टाइमस्टैम्प में सेट है:
console.log(Date.parse("1/1/1970"));
console.log(Date.parse("1/1/1970 12:00:00 AM"));
console.log(Date.parse("Thu Jan 01 1970"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00 GMT-0500"));
हालाँकि, ECMA-262 में निर्दिष्ट प्रारूपों के पार्स करने के बाद भी यह संगत नहीं है, यह अनुशंसित है कि बिल्ट-इन पार्सर पर भरोसा न करें और हमेशा मैन्युअल रूप से पार्स स्ट्रिंग्स, लाइब्रेरी का उपयोग करके कहें और पार्सर को प्रारूप प्रदान करें।
उदाहरण के लिए क्षण में। आप लिख सकते हैं:
let m = moment('1/1/1970', 'M/D/YYYY');
आउटपुट साइड
आउटपुट पक्ष पर, सभी ब्राउज़र टाइम ज़ोन का उसी तरह अनुवाद करते हैं, लेकिन वे स्ट्रिंग स्वरूपों को अलग तरीके से संभालते हैं। यहाँ toString
फ़ंक्शंस हैं और वे क्या आउटपुट देते हैं। मेरी मशीन पर 5:00 बजे आउटपुट toUTCString
और toISOString
फंक्शन्स को नोटिस करें । इसके अलावा, टाइमजोन नाम एक संक्षिप्त नाम हो सकता है और विभिन्न कार्यान्वयनों में भिन्न हो सकता है।
मुद्रण से पहले UTC से स्थानीय समय में कनवर्ट करता है
- toString
- toDateString
- toTimeString
- toLocaleString
- toLocaleDateString
- toLocaleTimeString
संग्रहीत UTC समय को सीधे प्रिंट करता है
- toUTCString
- toISOString
क्रोम में
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString Thu Jan 01 1970
toTimeString 00:00:00 GMT-05:00 (Eastern Standard Time)
toLocaleString 1/1/1970 12:00:00 AM
toLocaleDateString 1/1/1970
toLocaleTimeString 00:00:00 AM
toUTCString Thu, 01 Jan 1970 05:00:00 GMT
toISOString 1970-01-01T05:00:00.000Z
फ़ायरफ़ॉक्स में
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString Thu Jan 01 1970
toTimeString 00:00:00 GMT-0500 (Eastern Standard Time)
toLocaleString Thursday, January 01, 1970 12:00:00 AM
toLocaleDateString Thursday, January 01, 1970
toLocaleTimeString 12:00:00 AM
toUTCString Thu, 01 Jan 1970 05:00:00 GMT
toISOString 1970-01-01T05:00:00.000Z
मैं आमतौर पर स्ट्रिंग इनपुट के लिए आईएसओ प्रारूप का उपयोग नहीं करता हूं। केवल उस प्रारूप का उपयोग करना मेरे लिए फायदेमंद है, जब तारीखों को तार के रूप में हल करने की आवश्यकता होती है। आईएसओ प्रारूप के रूप में छांटे जाने योग्य है, जबकि अन्य नहीं हैं। यदि आपके पास क्रॉस-ब्राउज़र संगतता है, तो या तो टाइमज़ोन निर्दिष्ट करें या संगत स्ट्रिंग प्रारूप का उपयोग करें।
कोड new Date('12/4/2013').toString()
निम्नलिखित आंतरिक छद्म परिवर्तन के माध्यम से जाता है:
"12/4/2013" -> toUCT -> [storage] -> toLocal -> print "12/4/2013"
मुझे उम्मीद है कि यह उत्तर मददगार था।