Date.parse गलत परिणाम क्यों देता है?


345

केस एक:

new Date(Date.parse("Jul 8, 2005"));

आउटपुट:

शुक्र जुलाई 08 2005 00:00:00 GMT-0700 (PST)

केस दो:

new Date(Date.parse("2005-07-08"));

आउटपुट:

थू जुलाई 07 2005 17:00:00 GMT-0700 (PST)


दूसरा तोता गलत क्यों है?


30
दूसरा तोता गलत नहीं है प्रति, यह सिर्फ इतना है कि पहले स्थानीय समय में पार्स किया जाता है, और दूसरा यूटीसी में। ध्यान दें कि "थू जुल 07 2005 17:00:00 GMT-0700 (PST)" "2005-07-08 00:00" के समान है।
चुटकुले



1
यदि कोई व्यक्ति यह पता लगाने के लिए यहां आया कि NaNफ़ायरफ़ॉक्स में एक तारीख क्यों लौट रही है, तो मुझे पता चला कि अधिकांश अन्य ब्राउज़र (और Node.js) एक दिन के बिना एक तारीख को पार्स कर देंगे, जैसे कि "अप्रैल 2014" 1 अप्रैल 2014, लेकिन फ़ायरफ़ॉक्स NaN लौटाता है। आपको एक उचित तिथि पास करनी होगी।
जाजज़ी

ऊपर जेसन की टिप्पणी को जोड़ने के लिए: यदि आप फ़ायरफ़ॉक्स में एक NaN प्राप्त कर रहे हैं, तो एक और मुद्दा यह हो सकता है कि फ़ायरफ़ॉक्स और सफारी हाइफ़न तिथि को पसंद नहीं करते हैं। केवल क्रोम करता है। इसके बजाय एक स्लैश का उपयोग करें।
बैंकॉकियन

जवाबों:


451

जब तक 5 वें संस्करण की कल्पना सामने नहीं आई, तब तक यह Date.parseविधि पूरी तरह से कार्यान्वयन पर निर्भर थी ( new Date(string)यह Date.parse(string)बाद के रिटर्न को छोड़कर नंबर के बराबर है Date)। 5 वें संस्करण की कल्पना में, सरलीकृत (और थोड़ा गलत) आईएसओ -0101 का समर्थन करने के लिए आवश्यकता को जोड़ा गया था (यह भी देखें कि जावास्क्रिप्ट में मान्य दिनांक टाइम स्ट्रिंग्स क्या हैं? )। लेकिन इसके अलावा, इसके लिए कोई आवश्यकता नहीं थी Date.parse/ new Date(string)इसके अलावा अन्य को स्वीकार करना चाहिए कि उन्हें जो कुछ भी Date#toStringआउटपुट स्वीकार करना था (बिना यह कहे कि वह क्या था)।

ECMAScript 2017 (संस्करण 8) के अनुसार, कार्यान्वयन के लिए Date#toStringऔर उनके आउटपुट को पार्स करने की आवश्यकता थी Date#toUTCString, लेकिन उन तारों के प्रारूप को निर्दिष्ट नहीं किया गया था।

ECMAScript 2019 (संस्करण 9) के प्रारूप Date#toStringऔर Date#toUTCString(क्रमशः) के रूप में निर्दिष्ट किया गया है:

  1. ddd MMM DD YYYY HH: mm: ss ZZ [(timezone name)]
    जैसे Tue Jul 10 2018 18:39:58 GMT + 0530 (IST)
  2. ddd, DD MMM YYYY HH: mm: ss Z
    उदा। Tue 10 Jul 2018 13:09:58 GMT

2 और प्रारूप प्रदान Date.parseकरना चाहिए जो नए कार्यान्वयन में मज़बूती से पार्स करना चाहिए (यह देखते हुए कि समर्थन सर्वव्यापी नहीं है और गैर-अनुपालन कार्यान्वयन कुछ समय के लिए उपयोग में रहेंगे)।

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

// parse a date in yyyy-mm-dd format
function parseDate(input) {

  let parts = input.split('-');

  // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
  return new Date(parts[0], parts[1]-1, parts[2]); // Note: months are 0-based
}

बहुत बढ़िया, मुझे इसका इस्तेमाल करना Date.parseथा क्योंकि मैं किसी कारण से यूके डेट फॉर्मेट्स के साथ बर्ताव नहीं कर रहा था
बेन

1
समय भागों @CMS कोड में प्रलेखित हैं। मैंने "2012-01-31 12:00:00" की तिथि प्रारूप के साथ इस कोड का उपयोग किया return new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);, पूरी तरह से काम करता है, धन्यवाद!
रिचर्ड राउत

1
@ सीएमएस पर निर्भर कार्यान्वयन का क्या मतलब है ?
रॉय नमिर

3
@RoyiNamir, इसका मतलब है कि परिणाम इस बात पर निर्भर करते हैं कि वेब ब्राउज़र (या अन्य जावास्क्रिप्ट कार्यान्वयन) आपका कोड क्या चला रहा है।
सैमुअल एडविन वार्ड

1
मुझे अलग-अलग व्यवहार करने वाले अलग-अलग ब्राउज़रों में नई तिथि (स्ट्रिंग) के साथ भी समस्या हुई है। यह भी IE के पुराने संस्करणों पर तोड़े जाने का सवाल नहीं है, अलग-अलग ब्राउज़र अभी सुसंगत नहीं हैं। कभी भी Date.parse या नई दिनांक (स्ट्रिंग) का उपयोग न करें।
हॉफमैन

195

जेएस दुभाषिया लिखने के हाल के अनुभव के दौरान मैंने ईसीएमए / जेएस तिथियों के आंतरिक कामकाज के साथ बहुत कुश्ती की। इसलिए, मुझे लगता है कि मैं अपने 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"

मुझे उम्मीद है कि यह उत्तर मददगार था।


3
सबसे पहले, यह एक शानदार लेखन के रूप में। मैं हालांकि एक निर्भरता को इंगित करना चाहता था। टाइमज़ोन निर्दिष्टकर्ताओं के संबंध में, आपने कहा था: "एक विनिर्देशक की अनुपस्थिति को स्थानीय समय इनपुट मान लेना चाहिए।" शुक्र है, ECMA-262 मानक किसी भी ज़रूरत को मान लेता है। इसमें कहा गया है : "अनुपस्थित टाइम ज़ोन ऑफ़सेट का मान" Z "है।" इसलिए, निर्दिष्ट समय-सीमा के बिना एक तारीख / समय स्ट्रिंग को स्थानीय समय के बजाय एक यूटीसी माना जाता है। बेशक, बहुत सी चीजों के साथ जावास्क्रिप्ट के रूप में, कार्यान्वयन के बीच थोड़ा समझौता प्रतीत होता है।
डैनियल

2
... सहित अक्सर इस्तेमाल किया '1/1/1970' और '1/1/1970 00:00:00 AM' प्रारूप। - सबसे अधिक बार उपयोग कहां ? मेरे देश में यह सुनिश्चित नहीं है।
11

2
@ulidtko - क्षमा करें, मैं यूएस में हूं। वाह ... आप वहीं हैं कीव में। मुझे आशा है कि आप और आपका परिवार सुरक्षित रहेंगे और यह चीजें जल्द ही वहां पर स्थिर हो जाएंगी। अपना ख्याल रखें और हर चीज के साथ शुभकामनाएं दें।
drankin2112

बस यहाँ एक नोट। ऐसा लगता है कि यह सफ़ारी ब्राउज़र (यानी iOS या OSX) के लिए काम नहीं करता है। कि या मैं कुछ अन्य मुद्दा चल रहा है।
keyneom

1
@ डैनियल - सौभाग्य से ECMAScript लेखकों ने अपनी त्रुटि को समय और दिनांक अभ्यावेदन के लिए लापता समय क्षेत्र के संबंध में तय किया। अब एक टाइमज़ोन के बिना डेट और टाइम स्ट्रिंग्स होस्ट टाइमज़ोन ऑफ़सेट (यानी "स्थानीय") का उपयोग करते हैं। भ्रामक रूप से, आईएसओ 8601 तारीख को केवल यूटीसी के रूप में माना जाता है (भले ही यह विशेष रूप से कल्पना से स्पष्ट नहीं है), जबकि आईएसओ 8601 उन्हें स्थानीय मानता है, इसलिए उन्होंने सब कुछ ठीक नहीं किया।
RobG

70

पागलपन के लिए कुछ विधि है। एक सामान्य नियम के रूप में, यदि कोई ब्राउज़र किसी तारीख को ISO-8601 के रूप में व्याख्या कर सकता है, तो यह होगा। "2005-07-08" इस शिविर में आता है, और इसलिए इसे यूटीसी कहा जाता है। "जुलाई 8, 2005" नहीं कर सकता, और इसलिए इसे स्थानीय समय में पार्स किया जाता है।

देखें जावास्क्रिप्ट और खजूर, क्या एक मैस! अधिक जानकारी के लिए।


3
" एक सामान्य नियम के रूप में, यदि कोई ब्राउज़र किसी तिथि को ISO-8601 के रूप में व्याख्या कर सकता है, तो यह समर्थित नहीं होगा। " "2020-03-20 13:30:30" को कई ब्राउज़रों द्वारा आईएसओ 8601 और स्थानीय के रूप में माना जाता है, लेकिन सफारी द्वारा अमान्य दिनांक। कई आईएसओ 8601 प्रारूप हैं जो अधिकांश ब्राउज़रों द्वारा समर्थित नहीं हैं, जैसे 2004-W53-7 और 2020-092।
रॉब

7

एक अन्य समाधान तारीख प्रारूप और फिर सुधार डेटा के साथ एक सहयोगी सरणी का निर्माण करना है।

यह विधि एक असामान्य तरीके से स्वरूपित तिथि के लिए उपयोगी है।

एक उदाहरण:

    mydate='01.02.12 10:20:43':
    myformat='dd/mm/yy HH:MM:ss';


    dtsplit=mydate.split(/[\/ .:]/);
    dfsplit=myformat.split(/[\/ .:]/);

    // creates assoc array for date
    df = new Array();
    for(dc=0;dc<6;dc++) {
            df[dfsplit[dc]]=dtsplit[dc];
            }

    // uses assc array for standard mysql format
    dstring[r] = '20'+df['yy']+'-'+df['mm']+'-'+df['dd'];
    dstring[r] += ' '+df['HH']+':'+df['MM']+':'+df['ss'];

5

तारीखों को पार्स करने के लिए क्षणों का उपयोग करें :

var caseOne = moment("Jul 8, 2005", "MMM D, YYYY", true).toDate();
var caseTwo = moment("2005-07-08", "YYYY-MM-DD", true).toDate();

तीसरा तर्क सख्त पार्सिंग (2.3.0 के रूप में उपलब्ध) निर्धारित करता है। इसके बिना क्षण.जे गलत परिणाम भी दे सकते हैं।


4

Http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html के अनुसार प्रारूप "yyyy / mm / dd" सामान्य समस्याओं को हल करता है। वह कहते हैं: "जब भी संभव हो अपनी तार के लिए" YYYY / MM / DD "से चिपके रहें। यह सार्वभौमिक रूप से समर्थित और असंदिग्ध है। इस प्रारूप के साथ, सभी समय स्थानीय हैं।" मैंने परीक्षण सेट किए हैं: http://jsfiddle.net/jlanus/ND2Qg/432/ यह प्रारूप: + दिन और महीने के आदेश अस्पष्टता से बचाता है ymd आदेश का उपयोग करके और 4-अंक वर्ष + UTC से बचता है - स्थानीय मुद्दा नहीं स्लैग + डैनवैक, डॉग्ग्रेस आदमी का उपयोग करके आईएसओ प्रारूप का अनुपालन करते हुए , कहते हैं कि यह प्रारूप सभी ब्राउज़रों में अच्छा है।


आप लेखक का उत्तर देखना चाहते हैं ।
ब्रैड कोच

मैं कहूंगा कि jsFiddle में उदाहरण के साथ समाधान काफी अच्छा काम करता है यदि आप jQuery का उपयोग करते हैं क्योंकि यह डेटापिक पार्सर का उपयोग करता है। मेरे मामले में समस्या jqGrid के साथ है, लेकिन यह इसकी parseDate विधि है। लेकिन वैसे भी उदाहरण ने मुझे इसके लिए एक विचार देकर मुझे मदद की, इसके लिए धन्यवाद।
वासिल पोपोव

2
डाईग्राफ पर यह लेख गलत है और पृष्ठ पर पहला उदाहरण स्पष्ट रूप से दिखाता है कि हाइफ़न के बजाय स्लैश का उपयोग करना वास्तव में महत्वपूर्ण सलाह क्यों है। जिस समय लेख लिखा गया था, उस समय "2012/03/13" का उपयोग करते हुए ब्राउज़र ने UTC के बजाय इसे स्थानीय दिनांक के रूप में पार्स किया। ECMAScript विनिर्देशन "YYYY-MM-DD" (ISO8601) का उपयोग करने के लिए स्पष्ट समर्थन को परिभाषित करता है, इसलिए हमेशा हाइफ़न का उपयोग करें। यह ध्यान दिया जाना चाहिए कि जिस समय मैं यह टिप्पणी लिख रहा हूं, उस समय Chrome को UTC के रूप में स्लैश का इलाज करने के लिए पैच किया गया है।
लाचलान हंट

4

हालांकि सीएमएस सही है कि पार्स पद्धति में तार गुजरना आम तौर पर असुरक्षित है, खंड 15.9.4.2 में नया ECMA-262 5th संस्करण (उर्फ ES5) विनिर्देश बताता है कि Date.parse()वास्तव में आईएसओ-स्वरूपित तिथियों को संभालना चाहिए। पुराने विनिर्देशन ने ऐसा कोई दावा नहीं किया है। बेशक, पुराने ब्राउज़र और कुछ वर्तमान ब्राउज़र अभी भी इस ES5 कार्यक्षमता प्रदान नहीं करते हैं।

आपका दूसरा उदाहरण गलत नहीं है। यह यूटीसी में निर्दिष्ट तिथि है, जैसा कि निहित है Date.prototype.toISOString(), लेकिन आपके स्थानीय समयक्षेत्र में दर्शाया गया है।


1
और ईसीएमएस्क्रिप्ट 2015 में तारीखों के तार को फिर से बदल दिया गया था ताकि "2005-07-08" स्थानीय हो, यूटीसी नहीं। BTW, ES5 जून 2011 तक मानक नहीं था (और वर्तमान में ECMAScript 2015 है)। ;-)
रोबग

1
बस चीजों को भ्रमित करने के लिए, TC39 ने अक्टूबर का फैसला किया (मेरी पिछली पोस्ट के एक महीने बाद) कि "2005-07-08" UTC होना चाहिए , हालाँकि "" 2005-07-08T00: 00: 00 "स्थानीय होना चाहिए। दोनों आईएसओ 8601 हैं। आज्ञाकारी प्रारूप, दोनों एक समयक्षेत्र के बिना हैं, लेकिन अलग तरह से व्यवहार किया जाता है। जाओ आंकड़ा।
RobG

2

इस हल्के वजन की तारीख पार्सिंग लाइब्रेरी को सभी समान समस्याओं को हल करना चाहिए। मुझे पुस्तकालय पसंद है क्योंकि इसका विस्तार करना काफी आसान है। यह i18n के लिए भी संभव है (बहुत सीधे आगे नहीं, लेकिन इतना कठिन नहीं)।

पार्सिंग उदाहरण:

var caseOne = Date.parseDate("Jul 8, 2005", "M d, Y");
var caseTwo = Date.parseDate("2005-07-08", "Y-m-d");

और स्ट्रिंग को वापस स्वरूपित करना (आप देखेंगे कि दोनों मामले बिल्कुल समान परिणाम देंगे):

console.log( caseOne.dateFormat("M d, Y") );
console.log( caseTwo.dateFormat("M d, Y") );
console.log( caseOne.dateFormat("Y-m-d") );
console.log( caseTwo.dateFormat("Y-m-d") );

2

यहाँ एक संक्षिप्त, लचीला स्निपेट है, जिसे क्रॉस-ब्राउज़र-सुरक्षित फैशन में डेटाइम-स्ट्रिंग को निकेल के रूप में @ drankin2112 द्वारा विस्तृत रूप में परिवर्तित किया जा सकता है।

var inputTimestamp = "2014-04-29 13:00:15"; //example

var partsTimestamp = inputTimestamp.split(/[ \/:-]/g);
if(partsTimestamp.length < 6) {
    partsTimestamp = partsTimestamp.concat(['00', '00', '00'].slice(0, 6 - partsTimestamp.length));
}
//if your string-format is something like '7/02/2014'...
//use: var tstring = partsTimestamp.slice(0, 3).reverse().join('-');
var tstring = partsTimestamp.slice(0, 3).join('-');
tstring += 'T' + partsTimestamp.slice(3).join(':') + 'Z'; //configure as needed
var timestamp = Date.parse(tstring);

आपके ब्राउज़र को उसी टाइमस्टैम्प परिणाम के Date.parseसाथ प्रदान करना चाहिए :

(new Date(tstring)).getTime()

मैं पहले से ही JS-स्वरूपित तारीखों को पकड़ने के लिए regex में T जोड़ने का सुझाव दूंगा: inputTimestamp.split (/ [[T \ /: -] / g)
andig

यदि आप स्ट्रिंग को घटक भागों में विभाजित करते हैं, तो सबसे विश्वसनीय अगला चरण उन भागों का उपयोग तिथि निर्माणकर्ता के तर्क के रूप में करना है। पार्सर को देने के लिए एक और स्ट्रिंग बनाना बस आपको चरण 1 पर वापस लाता है। "2014-04-29 13:00:15" को स्थानीय के रूप में पार्स किया जाना चाहिए, आपका कोड इसे यूटीसी के रूप में पुन: प्रारूपित करता है। :-(
रॉब

2

दोनों सही हैं, लेकिन दो अलग-अलग टाइमज़ोन के साथ तारीखों के रूप में उनकी व्याख्या की जा रही है। तो आपने सेब और संतरे की तुलना की:

// local dates
new Date("Jul 8, 2005").toISOString()            // "2005-07-08T07:00:00.000Z"
new Date("2005-07-08T00:00-07:00").toISOString() // "2005-07-08T07:00:00.000Z"
// UTC dates
new Date("Jul 8, 2005 UTC").toISOString()        // "2005-07-08T00:00:00.000Z"
new Date("2005-07-08").toISOString()             // "2005-07-08T00:00:00.000Z"

मैंने Date.parse()कॉल को तब से हटा दिया जब से यह एक स्ट्रिंग तर्क पर स्वचालित रूप से उपयोग किया जाता है। मैंने ISO8601 प्रारूप का उपयोग करते हुए तारीखों की तुलना भी की ताकि आप अपनी स्थानीय तिथियों और UTC तिथियों के बीच की तारीखों की तुलना कर सकें। समय 7 घंटे अलग हैं, जो कि समयक्षेत्र अंतर है और आपके परीक्षणों ने दो अलग-अलग तिथियां क्यों दिखाईं।

इन स्थानीय / UTC तारीखों को बनाने का दूसरा तरीका यह होगा:

new Date(2005, 7-1, 8)           // "2005-07-08T07:00:00.000Z"
new Date(Date.UTC(2005, 7-1, 8)) // "2005-07-08T00:00:00.000Z"

लेकिन मैं अभी भी Moment.js की दृढ़ता से अनुशंसा करता हूं जो कि अभी तक सरल है :

// parse string
moment("2005-07-08").format()       // "2005-07-08T00:00:00+02:00"
moment.utc("2005-07-08").format()   // "2005-07-08T00:00:00Z"
// year, month, day, etc.
moment([2005, 7-1, 8]).format()     // "2005-07-08T00:00:00+02:00"
moment.utc([2005, 7-1, 8]).format() // "2005-07-08T00:00:00Z"

0

सीएमएस से स्वीकार किए जाते हैं जवाब सही है, तो मैं सिर्फ कुछ सुविधाओं को शामिल किया है:

  • ट्रिम और स्वच्छ इनपुट रिक्त स्थान
  • पार्स स्लैश, डैश, कॉलन और रिक्त स्थान
  • डिफ़ॉल्ट दिन और समय है

// parse a date time that can contains spaces, dashes, slashes, colons
function parseDate(input) {
    // trimes and remove multiple spaces and split by expected characters
    var parts = input.trim().replace(/ +(?= )/g,'').split(/[\s-\/:]/)
    // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
    return new Date(parts[0], parts[1]-1, parts[2] || 1, parts[3] || 0, parts[4] || 0, parts[5] || 0); // Note: months are 0-based
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.