타임 존이되기 전에
날짜 객체를 사용하여 날짜를 바로 표현하면 엄청난 정밀도 문제가 발생합니다. 시간과 시간대를 관리하여 시간을 절약해야하며 어느 단계에서나 다시 몰래 들어갈 수 있습니다. 이 질문에 대한 대답은 함정에 빠지게됩니다.
자바 스크립트 날짜에는 시간대 개념 이 없습니다 . 기본적으로 장치의 "로컬"시간대 또는 지정된 경우 UTC 또는 다른 시간대를 사용하여 문자열을주고받는 편리한 (정적) 기능을 갖춘 순간 (에포크 이후의 틱)입니다. 날짜 객체로 just-a-date ™ 를 나타내려면 날짜가 해당 날짜의 시작 부분에 UTC 자정을 나타내기를 원합니다. 이것은 생성의 계절이나 시간대에 관계없이 날짜로 작업 할 수있게하는 일반적이고 필요한 규칙입니다. 따라서 자정 UTC Date 객체를 만들거나 직렬화 할 때 시간대 개념을 관리하려면 매우주의해야합니다.
콘솔의 기본 동작으로 인해 많은 사람들이 혼동됩니다. 콘솔에 날짜를 뿌릴 경우 시간대가 포함 된 출력이 표시됩니다. 이것은 콘솔이 toString()
날짜를 부르고 toString()
현지 에서 설명하기 때문 입니다. 기본 날짜 는 시간대가 없습니다 ! (시간이 표준 시간대 오프셋과 일치하는 한 자정 UTC 날짜 개체가 있습니다)
역 직렬화 (또는 자정 UTC Date 객체 생성)
이것은 반올림 단계이며, 두 가지 "올바른"답변이 있습니다. 대부분의 경우, 날짜는 사용자의 시간대를 반영하기를 원할 것입니다. 오늘이 생일이라면 클릭하십시오 . NZ와 미국 사용자는 동시에 클릭하여 다른 날짜를 얻습니다. 이 경우, 이렇게하십시오 ...
// 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 형식입니다. 역 직렬화하려면 다음을 수행하십시오.
var midnightUTCDate = new Date( dateString + 'T00:00:00Z');
직렬화
시간대를 만들 때주의를 기울인 후에는 문자열 표현으로 다시 변환 할 때 시간대를 유지해야합니다. 안전하게 사용할 수 있습니다 ...
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 업데이트 ... 무료 ...
이 답변의 인기를 감안할 때 코드에 모두 넣었습니다. 다음 함수는 랩핑 된 날짜 오브젝트를 리턴하고 just-a-date ™와 함께 사용하기에 안전한 함수 만 노출합니다.
Date 객체로 호출하면 사용자의 시간대를 반영하여 JustADate로 해석됩니다. 문자열로 호출하십시오. 문자열이 시간대가 지정된 ISO 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()
. 기묘.