UFO ET IT

자바 스크립트의 날짜 차이 (시간 무시)

ufoet 2021. 1. 14. 07:51
반응형

자바 스크립트의 날짜 차이 (시간 무시)


임대 기간 (일)을 기준으로 고객에게 장비 임대료를 청구하는 장비 임대 신청서를 작성하고 있습니다. 따라서 기본적으로 (일일 요금 * 일수) = 총 요금입니다.

클라이언트 측에 대한 즉각적인 피드백을 위해 Javascript를 사용하여 두 달력 날짜의 차이를 파악하려고합니다. 나는 주변을 수색했지만 내가 찾은 것은 내가 찾고있는 것이 아니다. 내가 본 대부분의 솔루션은 다음과 같은 형식입니다.

function dateDiff1(startDate, endDate) {
    return ((endDate.getTime() - startDate.getTime()) / 1000*60*60*24);
}

내 문제는이 두 날짜 동안 추가 비용없이 하루언제든지 장비를 체크 아웃하고 반환 할 수 있다는 것입니다. 위의 코드는 두 날짜 사이의 24 시간 기간을 계산하고 있는데, 저는 달력 일수에 정말 관심이 있습니다.

예를 들어 누군가가 7 월 6 일 오전 6시에 장비를 체크 아웃하고 7 월 7 일 오후 10시에 반납했다면 위의 코드는 24 시간 이상이 지난 것으로 계산하고 2를 반환합니다. 원하는 결과는 1입니다. 하나의 달력 날짜가 경과했습니다 (예 : 6 일에서 7 일).

내가 찾은 가장 가까운 해결책은이 함수입니다.

function dateDiff2(startDate, endDate) {
    return endDate.getDate() - startDate.getDate();
}

두 날짜가 같은 달에있는 한 내가 원하는 것을 정확히 수행합니다. 그러나 getDate ()는 날짜 (예 : 1-31) 만 반환하므로 날짜가 여러 달에 걸쳐있는 경우에는 작동하지 않습니다 (예 : 7 월 31 일에서 8 월 1 일이 1 일이지만 위의 결과는 1-31을 계산합니다. -29).

백엔드에서는 PHP에서 gregoriantojd ()를 사용하고 있습니다. 이것은 잘 작동하는 것 같습니다 (예를 보려면 이 게시물 참조 ). Javascript에서 동등한 솔루션을 찾을 수 없습니다.

누구나 아이디어가 있습니까?


학생 카메라 대여 예를 위해 하루 종일 원하는 경우 ...

function daysBetween(first, second) {

    // Copy date parts of the timestamps, discarding the time parts.
    var one = new Date(first.getFullYear(), first.getMonth(), first.getDate());
    var two = new Date(second.getFullYear(), second.getMonth(), second.getDate());

    // Do the math.
    var millisecondsPerDay = 1000 * 60 * 60 * 24;
    var millisBetween = two.getTime() - one.getTime();
    var days = millisBetween / millisecondsPerDay;

    // Round down.
    return Math.floor(days);
}

나는 방금이 문제가 있었고이 질문을 찾은 후에 해결했기 때문에 이것을 게시하기 위해 돌아 왔습니다. 이것은 시간에 관계없이 총 일수를 얻습니다. 그리고 DST는 그것을 엉망으로 만들지 않습니다.

date1 = Date.UTC(date1.getFullYear(), date1.getMonth(), date1.getDate());
date2 = Date.UTC(date2.getFullYear(), date2.getMonth(), date2.getDate());
var ms = Math.abs(date1-date2);
return Math.floor(ms/1000/60/60/24); //floor should be unnecessary, but just in case

트릭은 원래 날짜의 시간을 알지 못하는 UTC 날짜로 변환하는 것입니다.


내가 할 일은 두 날짜의 시간을 같은 시간으로 설정하는 것입니다. 예를 들어 endDate의 시간을 12:00 am으로 설정하고 startDate의 시간도 12:00 am으로 설정합니다. 그런 다음 그들 사이의 차이를 얻으십시오.

참고로 나도 렌탈 장비 소프트웨어 업계에 있기 때문에 시간을 세지 않아 렌탈 수익을 잃는 것 같습니다. 예를 들어 누군가가 7 월 6 일 오전 6시에 장비를 집어 들고 7 월 7 일 오후 10시에 반납했다면. 그들은 장비를 사용하는 데 이틀이 걸렸고 아마도 초과 미터 요금이 발생할 수도 있습니다 ...


주어진 솔루션에 버그가 있습니다!

이것은 시간이 무시되고 정수 결과, 즉 전체 일 수를 원하는 날짜 차이에 적용됩니다.

위의 많은 예에서 Math.floor 다른 인스턴스를 볼 수 있습니다. Math.ceil도 다른 곳에서 본 적이 있습니다. 결과를 정수 일 수로 반올림하기 위해 수행됩니다. 문제는 일광 절약 시간이 Math.ceil을 사용하여 가을에 잘못된 결과를 제공한다는 것입니다. 결과는 언젠가 너무 커지거나 Math.floor를 사용하면 봄에 하루가 너무 적어 질 것입니다. 1 시간이 결과를 왜곡하지 않기 때문에 Math.round를 사용하십시오.

function dateDiff(dateEarlier, dateLater) {
    var one_day=1000*60*60*24
    return (  Math.round((dateLater.getTime()-dateEarlier.getTime())/one_day)  );
}

또한 놀라운 moment.js 라이브러리를 살펴볼 것을 제안 합니다. diff다음과 같이 위의 예를 해결하는 데 사용할 수 있는 다목적 기능이 있습니다.

function is_same_date(startDate, endDate) {
   var startMoment = moment(startDate).clone().startOf('day'),
       endMoment = moment(endDate).clone().startOf('day');
   return startMoment.diff(endMoment, 'days') == 0;
}

다음은 moment.jsdiff를 사용한 몇 가지 예입니다 .

> d1 = new Date(2012,04,04,0,0)
Fri May 04 2012 00:00:00 GMT-0400 (EDT)

> d2 = new Date(2012,04,03,23,0)
Thu May 03 2012 23:00:00 GMT-0400 (EDT)

> d3 = new Date(2012,04,05,23,0)
Sat May 05 2012 23:00:00 GMT-0400 (EDT)

> moment(d2).diff(d1, 'days')
0

> moment(d1).diff(d2, 'days')
0

> moment(d1).diff(d3, 'days') // uh oh. this is why we use `startOf`
-2

> moment(d2).diff(d3, 'days')
-2

> moment(d3).startOf('day') // this modified d3, sets the time to 00:00:00.0000
> d3
Sat May 05 2012 00:00:00 GMT-0400 (EDT)

시간대가 문제가되는 경우를 사용 moment.utc()하여 정규화 된 시간대로 변환 할 수도 있습니다 .


율리우스 력 날은 사실상 특정 날짜 이후의 일수 (일부 경우에는 일수의 비율)이므로 실제로 다르게 표시되는 UNIX 타임 스탬프와 동일합니다. 다음과 같이 1970 년 이후 전체 일 수를 얻을 수 있습니다.

Date.prototype.getWholeDays = function () {
    return Math.floor(new Date() / 1000*60*60*24);
};

function dateDiff(startDate, endDate) {
    return endDate.getWholeDays() - startDate.getWholeDays();
}

일의 차이 만 원하는 경우 UTC (GMT)를 사용하십시오. 그렇지 않으면 일광 절약 시간이 해당 간격 동안 시작되거나 종료되는 경우 빼기가 전체 일 수를 초 단위로 생성하지 않습니다.


18 세기 Excel에서 .getTime ()을 사용하는 datediff 함수의 결과를 확인했습니다. 결과가 올바로 반환됩니다. 다른 날짜를 계산하는 다른 방법이 있습니다.

    function DaysOfYear(nYear) {
        if ((nYear % 4) == 0) {
            return 366;
        }
        else {
            return 365;
        }
    }


    function DiffDays(fDate, tDate) {
        var fYear = fDate.getFullYear();
        var tYear = tDate.getFullYear();
        var fMonth = fDate.getMonth();
        var tMonth = tDate.getMonth();
        var fDay = fDate.getDate();
        var tDay = tDate.getDate();
        var nDays = 0;

        if (tYear > fYear) {   // different year
            // remain days of from year
            nDays = DaysOfYear(fYear) - YTD_Days(fDate);
            // days of between fYear to tYear
            for (y = (fYear + 1); y < tYear; y++) {
                nDays = nDays + DaysOfYear(y);
            }
            // days from the beginning of tYear
            nDays = nDays + YTD_Days(tDate);
        }
        else {   // in the same year
            nDays = YTD_Days(tDate) - YTD_Days(fDate);
        };
        return nDays;
    }

    function YTD_Days(dDate) {
        var y = dDate.getFullYear();
        var m = dDate.getMonth();
        var nDays = 0

        for (i = 0; i < m; i++) {
            switch (i) {
                case 0:     // January
                    nDays = nDays + 31;
                    break;
                case 1:     // February
                    if ((y % 4) == 0) {
                        nDays = nDays + 29;
                    }
                    else {
                        nDays = nDays + 28;
                    };
                    break;
                case 2:     // March
                    nDays = nDays + 31;
                    break;
                case 3:     // April
                    nDays = nDays + 30;
                    break;
                case 4:     // May
                    nDays = nDays + 31;
                    break;
                case 5:     // June
                    nDays = nDays + 30;
                    break;
                case 6:     // July
                    nDays = nDays + 31;
                    break;
                case 7:     // August
                    nDays = nDays + 31;
                    break;
                case 8:     // September
                    nDays = nDays + 30;
                    break;
                case 9:     // October
                    nDays = nDays + 31;
                    break;
                case 10:     // November
                    nDays = nDays + 30;
                    break;
                case 11:     // December
                    nDays = nDays + 31;
                    break;
            }
        }
        nDays = nDays + dDate.getDate();
        return nDays;
    }

시작 날짜를 같은 날 자정으로 조정 한 다음 날짜 사이의 24 시간 기간 수를 계산할 수 있습니다. 그런 다음 하루 중 일부를 하루 종일로 계산할지 여부에 따라 해당 숫자의 상한 또는 하한을 선택합니다.

function dateDiff(startDate, endDate) {
    // set startDate to the beginning of the day
    startDate = new Date(
        startDate.getFullYear(),
        startDate.getMonth(),
        startDate.getDate());

    return Math.floor((endDate - startDate) / 1000*60*60*24);
}

일 수가 0이 될 수 없다고 가정하여 setHours () 메서드를 사용하십시오. :)

function dateDiff1(startDate, endDate) {
    endDate.setHours(0);
    startDate.setHours(0);
    //assuming days cannt be 0.

    var x = ((endDate.getTime() - startDate.getTime()) / 1000*60*60*24);
    if (x <1 && x>=0) {
        return 1;
    }
    return x;
}

전체 요일을 얻으려면 일광 절약 시간제에 대한 날짜 간격이 변경되는 플로어 (일)를 라운드로 바꿔야합니다. 그렇지 않으면 매우 유용한 기능입니다.


+ UTC 생성자를 사용하는 위의 예. 그렇게하지 않으면 일광 절약 시간제 / 여름 시간에 휩쓸 릴 것입니다.

If you take the differences in some of them, it could wind up an hour short when crossing the DST line for your time zone in one direction (spring-forward, meaning in Feb asking for April, for example). When you floor N+23/24, you'll end up with N.

The other direction (in October asking for December) should be fine, you'll end up an hour ahead which the floor() will deal with correctly.


Just out of curiosity:

If you can affirm that the outcome will ALWAYS be < 31 days, then the following is a solution too:

var deltaDays = new Date(endDate - startDate).getDate()-1

Why?

Well decomposing the previous line:

var msecs = endDate - startDate; // difference in milliseconds
var dt = new Date(msecs); // will give us a date object pointing to a time 
                          // somewhere in Jan 1970 (given the precondition above)
var days = dt.getDate();  // Take the day part of it
var deltaDays = days - 1; // since the numbering starts from 1, we have to 
                          // substract 1 (Ex. if the diff in msecs is 0. The
                          // Date will point to 1st of Jan 1970)

But obviously you should NOT use it if your results can be > 31.


Need date.js, http://code.google.com/p/datejs/

function CalculateDuration(startDate, endDate) {

var sdt = Date.parse(startDate);
var edt = Date.parse(endDate);

var sdtYear = sdt.getYear();
var edtYear = edt.getYear();
var sdtMonth = sdt.getMonth();
var edtMonth = edt.getMonth();
var sdtDay = sdt.getDate();
var edtDay = edt.getDate();

var StartDateMonthDays = Date.getDaysInMonth(sdtYear, sdtMonth);
var EndDateMonthDays = Date.getDaysInMonth(edtYear, edtMonth);

if (edtMonth < sdtMonth) { //Means the ending month is earlier, which invalidates the operation

    alert("Ending month cannot be earlier than the starting month")

}

//Months are equal, if month is the next month of the start date month, 
//the operation fails, thus we need to calculate month difference first
else if (edtMonth > sdtMonth) {

    //Need to count how many days are left to finish the month
    var daysToMonthFinish = StartDateMonthDays - sdtDay;
    var calculatedDuration = daysToMonthFinish + edtDay;
    $("#hdn_duration").val(calculatedDuration);

}
//If months are the same, it is safe to just calculate the end day minus the start day
else {

    var calcDuration = edtDay - sdtDay;
    $("#hdn_duration").val(calcDuration);
}

I know this is a partial solution but you may be able to get the days between dates (as long as the dates don't have time set). Then you can work from there.

I'm basing this solution with the problem you presented ((daily fee * number of days) = total charge); not the actual date difference question. This should help you out.

var Main = function() {
    var startDate = new Date('08/20/2014');
    var endDate = new Date('08/22/2014');
    var totalCharge = monthlyFee * daysBetween(startDate, endDate);
}

var daysBetween = function(startDate, endDate) {
    return Math.round(Math.abs((startDate.getTime() - endDate.getTime())/(24*60*60*1000)));
};

ReferenceURL : https://stackoverflow.com/questions/1036742/date-difference-in-javascript-ignoring-time-of-day

반응형