TIMEZONE से सावधान रहें
सीधे-सीधे दिनांक का प्रतिनिधित्व करने के लिए दिनांक ऑब्जेक्ट का उपयोग करना आपको एक बड़ी अतिरिक्त परिशुद्धता समस्या में लाता है। आपको उन्हें बाहर रखने के लिए समय और समय-क्षेत्र का प्रबंधन करने की आवश्यकता है, और वे किसी भी चरण में वापस चुपके कर सकते हैं। इस प्रश्न का स्वीकृत उत्तर जाल में आता है।
एक जावास्क्रिप्ट तिथि में समयक्षेत्र की कोई धारणा नहीं है । यह डिवाइस के "स्थानीय" समय क्षेत्र, या, यदि निर्दिष्ट हो, यूटीसी या किसी अन्य समयक्षेत्र का उपयोग करके डिफ़ॉल्ट रूप से उपयोग करते हुए या स्ट्रिंग्स से अनुवाद करने के लिए आसान (स्थिर) कार्यों के साथ समय का एक क्षण है (महाकाव्य के बाद से)। दिनांक ऑब्जेक्ट के साथ बस-एक तारीख ™ का प्रतिनिधित्व करने के लिए , आप चाहते हैं कि आपकी तिथियां UTC का प्रतिनिधित्व करने के लिए मध्यरात्रि में दिनांक की शुरुआत में करें। यह एक आम और आवश्यक सम्मेलन है जो आपको उनकी रचना के मौसम या समयक्षेत्र की परवाह किए बिना तारीखों के साथ काम करने देता है। इसलिए, जब आप अपनी मध्यरात्रि UTC दिनांक ऑब्जेक्ट बनाते हैं, और जब आप इसे क्रमबद्ध करते हैं, तो टाइमज़ोन की धारणा को प्रबंधित करने के लिए आपको बहुत सतर्क रहने की आवश्यकता होती है।
कंसोल के डिफ़ॉल्ट व्यवहार से बहुत से लोग भ्रमित होते हैं। यदि आप किसी दिनांक को कंसोल पर स्प्रे करते हैं, तो आपके द्वारा देखे जाने वाले आउटपुट में आपका टाइमज़ोन शामिल होगा। यह सिर्फ इसलिए है क्योंकि कंसोल toString()
आपकी तिथि पर कॉल करता है, और toString()
आपको एक स्थानीय रीपेनेशन प्रदान करता है। अंतर्निहित तिथि का कोई समयक्षेत्र नहीं है ! (जब तक समय समय-समय पर ऑफसेट से मेल खाता है, तब भी आपके पास मध्यरात्रि यूटीसी तिथि वस्तु है)
Deserializing (या मध्यरात्रि UTC दिनांक ऑब्जेक्ट्स बनाना)
यह गोल कदम है, इस चाल के साथ कि दो "सही" उत्तर हैं। अधिकांश समय, आप चाहते हैं कि आपकी तिथि उपयोगकर्ता के समय क्षेत्र को प्रतिबिंबित करे। अगर आपका जन्मदिन है तो क्लिक करें । NZ और US के उपयोगकर्ता एक ही समय पर क्लिक करते हैं और अलग-अलग दिनांक प्राप्त करते हैं। उस मामले में, यह करें ...
// create a date (utc midnight) reflecting the value of myDate and the environment's timezone offset.
new Date(Date.UTC(myDate.getFullYear(),myDate.getMonth(), myDate.getDate()));
कभी-कभी, अंतर्राष्ट्रीय तुलनीयता स्थानीय सटीकता को प्रभावित करती है। उस मामले में, यह करें ...
// the date in London of a moment in time. Device timezone is ignored.
new Date(Date.UTC(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate()));
एक तिथि का वर्णन करें
अक्सर तार पर तारीखें YYYY-MM-DD प्रारूप में होंगी। उन्हें deserialize करने के लिए, ऐसा करें ...
var midnightUTCDate = new Date( dateString + 'T00:00:00Z');
serializing
जब आप बनाते समय टाइमज़ोन का प्रबंधन करने के लिए ध्यान रखते हैं, तो अब आपको टाइमज़ोन को बाहर रखने के लिए सुनिश्चित करने की आवश्यकता है जब आप एक स्ट्रिंग प्रतिनिधित्व में वापस बदलते हैं। तो आप सुरक्षित रूप से उपयोग कर सकते हैं ...
toISOString()
getUTCxxx()
getTime() //returns a number with no time or timezone.
.toLocaleDateString("fr",{timezone:"UTC"}) // whatever locale you want, but ALWAYS UTC.
और पूरी तरह से बाकी सब से बचें, खासकर ...
getYear()
, getMonth()
,getDate()
तो आपके सवाल का जवाब देने के लिए 7 साल बहुत देर ...
<input type="date" onchange="isInPast(event)">
<script>
var isInPast = function(event){
var userEntered = new Date(event.target.valueAsNumber); // valueAsNumber has no time or timezone!
var now = new Date();
var today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() ));
if(userEntered.getTime() < today.getTime())
alert("date is past");
else if(userEntered.getTime() == today.getTime())
alert("date is today");
else
alert("date is future");
}
</script>
इसे चलाकर देखें ...
अपडेट 2019 ... मुफ्त सामान ...
इस उत्तर की लोकप्रियता को देखते हुए, मैंने यह सब कोड में डाल दिया है। निम्न फ़ंक्शन एक लिपटे दिनांक ऑब्जेक्ट लौटाता है, और केवल उन कार्यों को उजागर करता है जो बस-ए-डेट ™ के साथ उपयोग करने के लिए सुरक्षित हैं।
इसे दिनांक ऑब्जेक्ट के साथ कॉल करें और यह उपयोगकर्ता के समय क्षेत्र को दर्शाते हुए जस्टडेट को हल करेगा। इसे एक स्ट्रिंग के साथ कॉल करें: यदि स्ट्रिंग एक आईएसओ 8601 है जिसमें टाइमज़ोन निर्दिष्ट है, तो हम केवल समय भाग को राउंड ऑफ करेंगे। यदि टाइमज़ोन निर्दिष्ट नहीं है, तो हम इसे स्थानीय टाइमज़ोन को दर्शाने वाली तिथि में परिवर्तित कर देंगे, जैसे कि तारीख वस्तुओं के लिए।
function JustADate(initDate){
var utcMidnightDateObj = null
// if no date supplied, use Now.
if(!initDate)
initDate = new Date();
// if initDate specifies a timezone offset, or is already UTC, just keep the date part, reflecting the date _in that timezone_
if(typeof initDate === "string" && initDate.match(/((\+|-)\d{2}:\d{2}|Z)$/gm)){
utcMidnightDateObj = new Date( initDate.substring(0,10) + 'T00:00:00Z');
} else {
// if init date is not already a date object, feed it to the date constructor.
if(!(initDate instanceof Date))
initDate = new Date(initDate);
// Vital Step! Strip time part. Create UTC midnight dateObj according to local timezone.
utcMidnightDateObj = new Date(Date.UTC(initDate.getFullYear(),initDate.getMonth(), initDate.getDate()));
}
return {
toISOString:()=>utcMidnightDateObj.toISOString(),
getUTCDate:()=>utcMidnightDateObj.getUTCDate(),
getUTCDay:()=>utcMidnightDateObj.getUTCDay(),
getUTCFullYear:()=>utcMidnightDateObj.getUTCFullYear(),
getUTCMonth:()=>utcMidnightDateObj.getUTCMonth(),
setUTCDate:(arg)=>utcMidnightDateObj.setUTCDate(arg),
setUTCFullYear:(arg)=>utcMidnightDateObj.setUTCFullYear(arg),
setUTCMonth:(arg)=>utcMidnightDateObj.setUTCMonth(arg),
addDays:(days)=>{
utcMidnightDateObj.setUTCDate(utcMidnightDateObj.getUTCDate + days)
},
toString:()=>utcMidnightDateObj.toString(),
toLocaleDateString:(locale,options)=>{
options = options || {};
options.timezone = "UTC";
locale = locale || "en-EN";
return utcMidnightDateObj.toLocaleDateString(locale,options)
}
}
}
// if initDate already has a timezone, we'll just use the date part directly
console.log(JustADate('1963-11-22T12:30:00-06:00').toLocaleDateString())
date1 === date2
लगातार व्यवहार प्रदान नहीं करता है; यह करनाdate1.valueOf() === b.valueOf()
या करना भी बेहतर हैdate1.getTime() === date2.getTime()
। विचित्रता।