क्यों "2016-02-16" "2016-02-16 00:00" के बराबर नहीं है?


96

मैं दोनों डेट स्ट्रिंग्स को पास करने की कोशिश कर रहा हूं new Date(t)

मुझे उम्मीद है कि दोनों तार एक ही समय का प्रतिनिधित्व करते हैं, आखिरकार, अगर मैं समय को छोड़ देता हूं, तो क्या उस दिन की आधी रात नहीं होनी चाहिए?

लेकिन, जबकि,

new Date("2016-02-16 00:00")

2016-02-16, आधी रात, उम्मीद के मुताबिक स्थानीय समय,

new Date("2016-02-16")

2016-02-16, मध्यरात्रि यूटीसी रिटर्न, जो गलत है, या कम से कम नहीं जो मैंने उम्मीद की थी कि अन्य स्ट्रिंग पर्स के रूप में दिए गए हैं।

मैं इसे समझूंगा कि क्या वे दोनों एक ही व्यवहार करेंगे, चाहे वह समय स्थानीय समय के रूप में वापस करना हो, या यूटीसी के रूप में, लेकिन यह बहुत असंगत लगता है कि वे इस तरह से अलग चीजें क्यों लौटाते हैं।

वर्कअराउंड के रूप में, जब भी मैं एक ऐसी तारीख का सामना करता हूं जिसमें कोई समान टाइमस्टैम्प नहीं होता है तो मैं लगातार व्यवहार प्राप्त करने के लिए "00:00" जोड़ सकता हूं, लेकिन ऐसा लगता है कि यह नाजुक है।

मुझे यह मान एक INPUT तत्व से मिल रहा है, टाइप 'डेटाइम-लोकल' इसलिए यह विशेष रूप से असंगत लगता है कि मुझे पेज तत्व द्वारा लौटाए गए मान के आसपास काम करना है।

क्या मैं कुछ गलत कर रहा हूं, या मुझे कुछ अलग करना चाहिए?


2
2016-02-16 00:00- यह बिल्कुल वैध समय की तरह नहीं दिखता है। ecma-international.org/ecma-262/6.0/... , लेकिन जाने के बाद भी डाल Tवहाँ यह वास्तव में अलग तरह से व्यवहार करती है
zerkms

वर्तमान में आप इसके मूल्य के आधार पर इनपुट तत्व से दिनांक वस्तु कैसे प्राप्त कर रहे हैं?
BoltClock

4
मानक के अनुसार - "यदि HH, मिमी, या ss फ़ील्ड अनुपस्थित हैं" 00 "का उपयोग मान के रूप में किया जाता है और अनुपस्थित sss फ़ील्ड का मान" 000 "है। यदि समय क्षेत्र ऑफ़सेट अनुपस्थित है, तो दिनांक-समय। स्थानीय समय के रूप में व्याख्या की जाती है। " --- इसे वैसा ही व्यवहार करना चाहिए।
झटके

@BoltClock हम्म, ऐसा लगता है कि यह तत्व का मान क्षेत्र ले रहा है और (जैसा कि झटकेदार ने देखा) किसी कारण से टी को हटा रहा है (मुझे लगता है क्योंकि मूल्य उपयोगकर्ता को एक संदर्भ में प्रदर्शित हो रहा है जहां "टी" भ्रमित हो जाएगा
माइकल

1
@ मिचेल: शानदार। इस तरह के ब्राउज़र मेरी पसंदीदा हैं। (? या यह एक डोम विनिर्देश मोड़ कोई विचार है, मैं वास्तव में देखा नहीं किया है हो सकता है।)
BoltClock

जवाबों:


100

यह ES5.1 विनिर्देशन क्या कहता है:

अनुपस्थित समय क्षेत्र ऑफ़सेट का मान "Z" है।

यह भी कहता है:

फ़ंक्शन पहले दिनांक समय स्ट्रिंग प्रारूप (15.9.1.15) में बताए गए नियमों के अनुसार स्ट्रिंग के प्रारूप को पार्स करने का प्रयास करता है। यदि स्ट्रिंग उस प्रारूप के अनुरूप नहीं है, तो फ़ंक्शन किसी भी कार्यान्वयन-विशिष्ट उत्तराधिकार या कार्यान्वयन-विशिष्ट दिनांक स्वरूपों पर वापस आ सकता है।

चूंकि प्रारूप को Tदिनांक और समय के बीच एक विभाजक की आवश्यकता होती है , इसलिए मान्य समय UTC पर जाएं:

> new Date("2016-02-16T00:00:00")
Tue Feb 16 2016 01:00:00 GMT+0100 (CET)
> new Date("2016-02-16")
Tue Feb 16 2016 01:00:00 GMT+0100 (CET)

... जबकि नोड में.जेएस, एक अमान्य समय (टी सेपरेटर के बिना) कार्यान्वयन के लिए जाने के लिए लगता है विशिष्ट स्थानीय समय:

> new Date("2016-02-16 00:00:00")
Tue Feb 16 2016 00:00:00 GMT+0100 (CET)

ध्यान दें कि ES6 ने इसे बदल दिया , प्रलेखन के एक ही हिस्से में यह बदल जाता है:

यदि समय क्षेत्र अनुपस्थित है, तो दिनांक-समय की व्याख्या स्थानीय समय के रूप में की जाती है।

ब्रेकिंग का आनंद बदल जाता है

संपादित करें

TC39 के अनुसार , विनिर्देश का अर्थ है कि समय क्षेत्र के बिना दिनांक और समय के तार के रूप में व्याख्या की जा सकती है (उदाहरण के लिए "2016-02-16T00: 00: 00") को स्थानीय माना जाता है (प्रति आईएसओ 8601), लेकिन तिथि केवल तार (जैसे "2016-02-16") यूटीसी के रूप में (जो आईएसओ 8601 के साथ असंगत है)।


20
वास्तव में, तोड़ने का आनंद। ES7 मानक के एक नए मसौदे में, UTC से स्थानीय समय में परिवर्तन का हिस्सा वापस कर दिया गया था । नए मानक का कहना है कि तिथियों की व्याख्या UTC के रूप में की जानी चाहिए, यदि कोई समय-सीमा निर्दिष्ट नहीं की गई है, जबकि तिथि-समय को स्थानीय समय के रूप में व्याख्या किया जाना चाहिए, यदि कोई समय-सीमा अधिकृत है।
hichris123

3
वे वास्तव में दोनों स्थानीय समय होने चाहिए, भले ही केवल तारीख या तारीख के रूप हों। इस तरह ISO8601 काम करता है। यह हास्यास्पद है कि मध्य-काल UTC के रूप में केवल-दिनांक के रूप में व्याख्या की जाती है, क्योंकि एक कालातीत UTC दिनांक भी वैचारिक रूप से समझ में नहीं आता है। ECMA tc39 में इस बारे में गरमागरम बहस हुई। मैंने स्थानीय समय के लिए संघर्ष किया, और हार गया। github.com/tc39/ecma262/issues/87
मैट जॉनसन-पिंट

10

विनिर्देशों के अनुसार :

फ़ंक्शन पहले दिनांक समय स्ट्रिंग प्रारूप (15.9.1.15) में बताए गए नियमों के अनुसार स्ट्रिंग के प्रारूप को पार्स करने का प्रयास करता है। यदि स्ट्रिंग उस प्रारूप के अनुरूप नहीं है, तो फ़ंक्शन किसी भी कार्यान्वयन-विशिष्ट उत्तराधिकार या कार्यान्वयन-विशिष्ट दिनांक स्वरूपों पर वापस आ सकता है।

और दिनांक समय स्ट्रिंग प्रारूप2016-02-16 एक मान्य दिनांक के रूप में स्वीकार करते हैं

इस प्रारूप में दिनांक-केवल फ़ॉर्म शामिल हैं:

YYYY
YYYY-MM
YYYY-MM-DD

[...] यदि HH, mm या ss फ़ील्ड अनुपस्थित हैं "00" का उपयोग मान के रूप में किया जाता है और अनुपस्थित sss फ़ील्ड का मान "000" है। अनुपस्थित समय क्षेत्र ऑफ़सेट का मान "Z" है।

इस प्रकार 2016-02-16अनुवाद करता है 2016-02-16T00:00:00.000Z

अन्य तिथि 2016-02-16 00:00प्रारूप के अनुरूप नहीं है और इसलिए इसका पार्सिंग कार्यान्वयन के लिए विशिष्ट है। जाहिरा तौर पर, ऐसी तिथियों को स्थानीय समय क्षेत्र के रूप में माना जाता है और आपकी उदाहरण तिथि समय क्षेत्र के आधार पर विभिन्न मान लौटाएगी:

/* tz = +05:00 */ new Date("2016-02-16 00:00").toISOString() // 2016-02-15T19:00:00.000Z
/* tz = -08:00 */ new Date("2016-02-16 00:00").toISOString() // 2016-02-16T08:00:00.000Z

सारांश:

  • दिनांक समय प्रारूपों के अनुरूप करने के लिए व्यवहार को अच्छी तरह से परिभाषित किया जाता है - समय क्षेत्र की अनुपस्थिति में दिनांक स्ट्रिंग को UTC (ES5) या स्थानीय (ES6) के रूप में माना जाता है।
  • गैर-अनुरूपण तिथि समय प्रारूपों के लिए व्यवहार विशिष्ट लागू हो रहा है - समय क्षेत्र की अनुपस्थिति में सामान्य व्यवहार की तारीख को स्थानीय मान लेना है।
  • तथ्य के रूप में, कार्यान्वयन गैर-अनुरूप तारीखों को पार्स करने NaNकी कोशिश करने के बजाय वापस लौटने का विकल्प चुन सकता है। इंटरनेट एक्सप्लोरर 11 में अपने कोड का परीक्षण करें;)

7

आप शायद ES5, ES6 कार्यान्वयन और आपके अपेक्षित परिणाम के बीच अंतर कर रहे हैं। MDN पर प्रति दिनांक । "विशेष रूप से विभिन्न ECMAScript कार्यान्वयनों में, जहां" 2015-10-12 12:00:00 "जैसे तार NaN, UTC या स्थानीय समयक्षेत्र के रूप में देखे जा सकते हैं, महत्वपूर्ण है।

फ़ायरफ़ॉक्स 44 और IE 11 में अतिरिक्त परीक्षण से पता चला है कि वे दोनों एक दिनांक ऑब्जेक्ट के लिए new Date("2016-02-16 00:00")लौटाते हैं, जिस ऑब्जेक्ट को NaN लौटाता है जब एक डेट कंपोनेंट मान प्राप्त करने के लिए प्रयास करते हैं, और जिसका स्ट्रींग मान "अमान्य दिनांक" ("NaN" नहीं) होता है। इसलिए "00:00 को सुसंगत व्यवहार प्राप्त करना" अलग-अलग ब्राउज़रों में आसानी से टूट सकता है।

जैसा कि अन्य उत्तरों में उल्लेख किया new Date("2016-02-16")गया है, डिफ़ॉल्ट रूप से शून्य का एक समयक्षेत्र ऑफसेट का उपयोग करता है, स्थानीय के बजाय मध्यरात्रि यूटीसी का उत्पादन करता है।


ओपी एक ही कार्यान्वयन पर अलग-अलग परिणाम प्राप्त करता है।
सलमान एक

6

DateParser::Parse()क्रोम के लिए प्रति V8 स्रोत कोड।

ES5 ISO 8601 दिनांक:

[('-'|'+')yy]yyyy[-MM[-DD]][THH:mm[:ss[.sss]][Z|(+|-)hh:mm]]

एक अहस्ताक्षरित संख्या जिसके बाद ':' एक समय मान है, और TimeComposer में जोड़ा जाता है।

यदि गुम हो जाए तो समय-क्षेत्र Z से चूक जाता है

> new Date("2016-02-16 00:00")
  Tue Feb 16 2016 00:00:00 GMT+0800 (China Standard Time)

एक स्ट्रिंग जो दोनों प्रारूपों (जैसे 1970-01-01) से मेल खाती है , उसे ES5 तिथि-समय स्ट्रिंग के रूप में पार्स किया जाएगा - जिसका अर्थ है कि यह UTC time-zonई के लिए डिफ़ॉल्ट होगा । ES5 विनिर्देशन का पालन करने पर यह अपरिहार्य है।

> new Date("2016-02-16")
Tue Feb 16 2016 08:00:00 GMT+0800 (China Standard Time)

3

2016-02-16, मध्यरात्रि यूटीसी रिटर्न, जो गलत है, या कम से कम नहीं जो मैंने उम्मीद की थी कि अन्य स्ट्रिंग पर्स के रूप में दिए गए हैं।

यह समय क्षेत्र ऑफसेट को जोड़ता है 00:00

new Date("2016-02-16") आउटपुट Tue Feb 16 2016 05:30:00 GMT+0530 (India Standard Time)

मेरा टाइमज़ोन एक ऑफसेट मूल्य (मिनटों में) के साथ IST है +330, इसलिए इसने 330 मिनट से 00:00 तक जोड़ा।

एक्मा -२६२ के अनुसार , धारा २०.३.३.२ दिनांक.पारंसी (स्ट्रिंग)

यदि टर्निंग स्ट्रिंग परिणाम अचानक पूरा होने का रिकॉर्ड तुरंत वापस आ जाता है। अन्यथा, पार्स परिणामी स्ट्रिंग को एक तिथि और समय के रूप में व्याख्या करता है; यह एक संख्या, UTC समय मान दिनांक और समय के अनुरूप देता है। स्ट्रिंग की सामग्री के आधार पर स्थानीय समय, UTC समय या किसी अन्य समय क्षेत्र में समय के रूप में व्याख्या की जा सकती है।

जब आप स्पष्ट रूप से सेट समय इकाइयों new Date("2016-02-16 00:00")यह wll उपयोग सेट के रूप में है कि hoursऔर minutes,

अन्यथा जैसा कि 2 0.3.1.16 में यहां बताया गया है

यदि समय क्षेत्र अनुपस्थित है, तो दिनांक-समय की व्याख्या स्थानीय समय के रूप में की जाती है।


हाँ, लेकिन यह एक मामले में ऐसा क्यों करता है लेकिन दूसरे को नहीं?
माइकल


तो वे अलग-अलग परिणाम क्यों हैं? मानक का दावा यह एक ही होना चाहिए
zerkms

@zerkms स्टैंडर्ड कहता है कि जब आप टाइम यूनिट पास करेंगे तो यह क्या करेगा, यह नहीं कहता कि जब आप नहीं करेंगे तो यह क्या करेगा। यह स्पष्ट रूप से कहता The String may be interpreted as a local time, a UTC time, or a time in some other time zone, depending on the contents of the String.है कि यह कहां दावा कर रहा है कि यह समान होना चाहिए?
गुरुविंदर

@ gurvinder372 मैंने प्रश्न टिप्पणियों में उद्धरण प्रदान किया है: "यदि HH, मिमी, या ss फ़ील्ड अनुपस्थित हैं" 00 "का उपयोग मान के रूप में किया जाता है और अनुपस्थित sss फ़ील्ड का मान" 000 "है। यदि समय क्षेत्र ऑफसेट है। अनुपस्थित है, दिनांक-समय की व्याख्या स्थानीय समय के रूप में की जाती है। "
झटके
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.