[javascript] JavaScript에서 시간을 비교하지 않고 날짜 부분 만 비교

아래 코드에 어떤 문제가 있습니까?

아마도 시간이 아닌 날짜를 비교하는 것이 더 간단 할 것입니다. 이 작업을 수행하는 방법을 모르고 검색했지만 정확한 문제를 찾을 수 없습니다.

BTW, 두 날짜를 경고에 표시하면 정확히 동일하게 표시됩니다.

내 코드 :

window.addEvent('domready', function() {
    var now = new Date();
    var input = $('datum').getValue();
    var dateArray = input.split('/');
    var userMonth = parseInt(dateArray[1])-1;
    var userDate = new Date();
    userDate.setFullYear(dateArray[2], userMonth, dateArray[0], now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds());

    if (userDate > now)
    {
        alert(now + '\n' + userDate);
    }
});

날짜를 비교하고 시간을 포함하지 않는 더 간단한 방법이 있습니까?



답변

나는 여전히 JavaScript를 배우고 있으며 시간없이 두 날짜를 비교하는 데 도움이되는 유일한 방법 setHours은 Date 객체 의 메서드 를 사용 하고 시간, 분, 초 및 밀리 초를 0으로 설정하는 것입니다. 그런 다음 두 날짜를 비교하십시오.

예를 들어

date1 = new Date()
date2 = new Date(2011,8,20)

date2은시, 분, 초 및 밀리 초로 0으로 설정되지만 date1은 date1이 작성된 시간으로 설정됩니다. date1에서 시간, 분, 초 및 밀리 초를 제거하려면 다음을 수행하십시오.

date1.setHours(0,0,0,0)

이제 시간 요소에 대한 걱정없이 두 날짜를 DATES로 비교할 수 있습니다.


답변

타임 존이되기 전에

날짜 객체를 사용하여 날짜를 바로 표현하면 엄청난 정밀도 문제가 발생합니다. 시간과 시간대를 관리하여 시간을 절약해야하며 어느 단계에서나 다시 몰래 들어갈 수 있습니다. 이 질문에 대한 대답은 함정에 빠지게됩니다.

자바 스크립트 날짜에는 시간대 개념없습니다 . 기본적으로 장치의 “로컬”시간대 또는 지정된 경우 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())


답변

이건 어때요?

Date.prototype.withoutTime = function () {
    var d = new Date(this);
    d.setHours(0, 0, 0, 0);
    return d;
}

변수 값에 영향을 미치지 않고 다음과 같이 날짜의 날짜 부분을 비교할 수 있습니다.

var date1 = new Date(2014,1,1);
new Date().withoutTime() > date1.withoutTime(); // true


답변

Moment.js 사용

타사 라이브러리를 포함시킬 수있는 옵션이 있다면 Moment.js를 살펴볼 가치가 있습니다. 이 작업을하게 Date하고 DateTime훨씬, 훨씬 쉽다.

예를 들어, 하나의 날짜가 다른 날짜 뒤에 오지만 시간을 제외하면 다음과 같이 할 수 있습니다.

var date1 = new Date(2016,9,20,12,0,0); // October 20, 2016 12:00:00
var date2 = new Date(2016,9,20,12,1,0); // October 20, 2016 12:01:00

// Comparison including time.
moment(date2).isAfter(date1); // => true

// Comparison excluding time.
moment(date2).isAfter(date1, 'day'); // => false

당신이에 전달하는 두 번째 매개 변수는 isAfter비교를 할 수있는 정밀하고도 될 수 있습니다 year, month, week, day, hour, minute또는 second.


답변

아래와 같이 .toDateString을 사용하여 간단히 비교하십시오.

new Date().toDateString();

이렇게하면 다음과 같이 시간이나 시간대가 아닌 날짜 부분 만 반환됩니다.

“2017 년 2 월 3 일 금요일”

따라서 두 날짜 모두 시간 형식없이이 형식으로 비교할 수 있습니다.


답변

이것은 좀 더 깔끔한 버전 일 수 있습니다. 또한 parseInt를 사용할 때는 항상 기수를 사용해야합니다.

window.addEvent('domready', function() {
    // Create a Date object set to midnight on today's date
    var today = new Date((new Date()).setHours(0, 0, 0, 0)),
    input = $('datum').getValue(),
    dateArray = input.split('/'),
    // Always specify a radix with parseInt(), setting the radix to 10 ensures that
    // the number is interpreted as a decimal.  It is particularly important with
    // dates, if the user had entered '09' for the month and you don't use a
    // radix '09' is interpreted as an octal number and parseInt would return 0, not 9!
    userMonth = parseInt(dateArray[1], 10) - 1,
    // Create a Date object set to midnight on the day the user specified
    userDate = new Date(dateArray[2], userMonth, dateArray[0], 0, 0, 0, 0);

    // Convert date objects to milliseconds and compare
    if(userDate.getTime() > today.getTime())
    {
            alert(today+'\n'+userDate);
    }
});

기수에 대한 자세한 내용은 MDC 구문 분석 페이지를 확인하십시오.

JSLint 는 누락 된 기수와 같은 것들을 포착하고 모호하고 디버깅하기 어려운 오류를 잡을 수있는 훌륭한 도구입니다. 더 나은 코딩 표준을 사용하도록하여 향후 두통을 피할 수 있습니다. 코드를 작성하는 모든 JavaScript 프로젝트에서 사용합니다.


답변

date.js의 라이브러리는 이러한 것들에 대한 편리합니다. 모든 JS 날짜 관련 스크립 핑을 훨씬 쉽게 만듭니다.