JavaScript 中的日期差异

如何找出两次约会之间的区别?

140485 次浏览

By using the Date object and its milliseconds value, differences can be calculated:

var a = new Date(); // Current date now.
var b = new Date(2010, 0, 1, 0, 0, 0, 0); // Start of 2010.
var d = (b-a); // Difference in milliseconds.

You can get the number of seconds (as a integer/whole number) by dividing the milliseconds by 1000 to convert it to seconds then converting the result to an integer (this removes the fractional part representing the milliseconds):

var seconds = parseInt((b-a)/1000);

You could then get whole minutes by dividing seconds by 60 and converting it to an integer, then hours by dividing minutes by 60 and converting it to an integer, then longer time units in the same way. From this, a function to get the maximum whole amount of a time unit in the value of a lower unit and the remainder lower unit can be created:

function get_whole_values(base_value, time_fractions) {
time_data = [base_value];
for (i = 0; i < time_fractions.length; i++) {
time_data.push(parseInt(time_data[i]/time_fractions[i]));
time_data[i] = time_data[i] % time_fractions[i];
}; return time_data;
};
// Input parameters below: base value of 72000 milliseconds, time fractions are
// 1000 (amount of milliseconds in a second) and 60 (amount of seconds in a minute).
console.log(get_whole_values(72000, [1000, 60]));
// -> [0,12,1] # 0 whole milliseconds, 12 whole seconds, 1 whole minute.

If you're wondering what the input parameters provided above for the second Date object are, see their names below:

new Date(<year>, <month>, <day>, <hours>, <minutes>, <seconds>, <milliseconds>);

As noted in the comments of this solution, you don't necessarily need to provide all these values unless they're necessary for the date you wish to represent.

    // This is for first date
first = new Date(2010, 03, 08, 15, 30, 10); // Get the first date epoch object
document.write((first.getTime())/1000); // get the actual epoch values
second = new Date(2012, 03, 08, 15, 30, 10); // Get the second date epoch object
document.write((second.getTime())/1000); // get the actual epoch values
diff= second - first ;
one_day_epoch = 24*60*60 ;  // calculating one epoch
if ( diff/ one_day_epoch > 365 ) // check if it is exceeding regular calendar year
{
alert( 'date is exceeding one year');
}

I have found this and it works fine for me:

Calculating the Difference between Two Known Dates

Unfortunately, calculating a date interval such as days, weeks, or months between two known dates is not as easy because you can't just add Date objects together. In order to use a Date object in any sort of calculation, we must first retrieve the Date's internal millisecond value, which is stored as a large integer. The function to do that is Date.getTime(). Once both Dates have been converted, subtracting the later one from the earlier one returns the difference in milliseconds. The desired interval can then be determined by dividing that number by the corresponding number of milliseconds. For instance, to obtain the number of days for a given number of milliseconds, we would divide by 86,400,000, the number of milliseconds in a day (1000 x 60 seconds x 60 minutes x 24 hours):

Date.daysBetween = function( date1, date2 ) {
//Get 1 day in milliseconds
var one_day=1000*60*60*24;


// Convert both dates to milliseconds
var date1_ms = date1.getTime();
var date2_ms = date2.getTime();


// Calculate the difference in milliseconds
var difference_ms = date2_ms - date1_ms;


// Convert back to days and return
return Math.round(difference_ms/one_day);
}


//Set the two dates
var y2k  = new Date(2000, 0, 1);
var Jan1st2010 = new Date(y2k.getFullYear() + 10, y2k.getMonth(), y2k.getDate());
var today= new Date();
//displays 726
console.log( 'Days since '
+ Jan1st2010.toLocaleDateString() + ': '
+ Date.daysBetween(Jan1st2010, today));

The rounding is optional, depending on whether you want partial days or not.

Reference

Date.prototype.addDays = function(days) {


var dat = new Date(this.valueOf())
dat.setDate(dat.getDate() + days);
return dat;
}


function getDates(startDate, stopDate) {


var dateArray = new Array();
var currentDate = startDate;
while (currentDate <= stopDate) {
dateArray.push(currentDate);
currentDate = currentDate.addDays(1);
}
return dateArray;
}


var dateArray = getDates(new Date(), (new Date().addDays(7)));


for (i = 0; i < dateArray.length; i ++ ) {
//  alert (dateArray[i]);


date=('0'+dateArray[i].getDate()).slice(-2);
month=('0' +(dateArray[i].getMonth()+1)).slice(-2);
year=dateArray[i].getFullYear();
alert(date+"-"+month+"-"+year );
}

If you are looking for a difference expressed as a combination of years, months, and days, I would suggest this function:

function interval(date1, date2) {
if (date1 > date2) { // swap
var result = interval(date2, date1);
result.years  = -result.years;
result.months = -result.months;
result.days   = -result.days;
result.hours  = -result.hours;
return result;
}
result = {
years:  date2.getYear()  - date1.getYear(),
months: date2.getMonth() - date1.getMonth(),
days:   date2.getDate()  - date1.getDate(),
hours:  date2.getHours() - date1.getHours()
};
if (result.hours < 0) {
result.days--;
result.hours += 24;
}
if (result.days < 0) {
result.months--;
// days = days left in date1's month,
//   plus days that have passed in date2's month
var copy1 = new Date(date1.getTime());
copy1.setDate(32);
result.days = 32-date1.getDate()-copy1.getDate()+date2.getDate();
}
if (result.months < 0) {
result.years--;
result.months+=12;
}
return result;
}


// Be aware that the month argument is zero-based (January = 0)
var date1 = new Date(2015, 4-1, 6);
var date2 = new Date(2015, 5-1, 9);


document.write(JSON.stringify(interval(date1, date2)));

This solution will treat leap years (29 February) and month length differences in a way we would naturally do (I think).

So for example, the interval between 28 February 2015 and 28 March 2015 will be considered exactly one month, not 28 days. If both those days are in 2016, the difference will still be exactly one month, not 29 days.

Dates with exactly the same month and day, but different year, will always have a difference of an exact number of years. So the difference between 2015-03-01 and 2016-03-01 will be exactly 1 year, not 1 year and 1 day (because of counting 365 days as 1 year).

var DateDiff = function(type, start, end) {


let // or var
years = end.getFullYear() - start.getFullYear(),
monthsStart = start.getMonth(),
monthsEnd = end.getMonth()
;


var returns = -1;


switch(type){
case 'm': case 'mm': case 'month': case 'months':
returns = ( ( ( years * 12 ) - ( 12 - monthsEnd ) ) + ( 12 - monthsStart ) );
break;
case 'y': case 'yy': case 'year': case 'years':
returns = years;
break;
case 'd': case 'dd': case 'day': case 'days':
returns = ( ( end - start ) / ( 1000 * 60 * 60 * 24 ) );
break;
}


return returns;


}

Usage

var qtMonths = DateDiff('mm', new Date('2015-05-05'), new Date());

var qtYears = DateDiff('yy', new Date('2015-05-05'), new Date());

var qtDays = DateDiff('dd', new Date('2015-05-05'), new Date());

OR

var qtMonths = DateDiff('m', new Date('2015-05-05'), new Date()); // m || y || d

var qtMonths = DateDiff('month', new Date('2015-05-05'), new Date()); // month || year || day

var qtMonths = DateDiff('months', new Date('2015-05-05'), new Date()); // months || years || days

...

var DateDiff = function (type, start, end) {


let // or var
years = end.getFullYear() - start.getFullYear(),
monthsStart = start.getMonth(),
monthsEnd = end.getMonth()
;


if(['m', 'mm', 'month', 'months'].includes(type)/*ES6*/)
return ( ( ( years * 12 ) - ( 12 - monthsEnd ) ) + ( 12 - monthsStart ) );
else if(['y', 'yy', 'year', 'years'].includes(type))
return years;
else if (['d', 'dd', 'day', 'days'].indexOf(type) !== -1/*EARLIER JAVASCRIPT VERSIONS*/)
return ( ( end - start ) / ( 1000 * 60 * 60 * 24 ) );
else
return -1;


}

This answer, based on another one (link at end), is about the difference between two dates.
You can see how it works because it's simple, also it includes splitting the difference into
units of time (a function that I made) and converting to UTC to stop time zone problems.

function date_units_diff(a, b, unit_amounts) {
var split_to_whole_units = function (milliseconds, unit_amounts) {
// unit_amounts = list/array of amounts of milliseconds in a
// second, seconds in a minute, etc., for example "[1000, 60]".
time_data = [milliseconds];
for (i = 0; i < unit_amounts.length; i++) {
time_data.push(parseInt(time_data[i] / unit_amounts[i]));
time_data[i] = time_data[i] % unit_amounts[i];
}; return time_data.reverse();
}; if (unit_amounts == undefined) {
unit_amounts = [1000, 60, 60, 24];
};
var utc_a = new Date(a.toUTCString());
var utc_b = new Date(b.toUTCString());
var diff = (utc_b - utc_a);
return split_to_whole_units(diff, unit_amounts);
}


// Example of use:
var d = date_units_diff(new Date(2010, 0, 1, 0, 0, 0, 0), new Date()).slice(0,-2);
document.write("In difference: 0 days, 1 hours, 2 minutes.".replace(
/0|1|2/g, function (x) {return String( d[Number(x)] );} ));

How my code above works

A date/time difference, as milliseconds, can be calculated using the Date object:

var a = new Date(); // Current date now.
var b = new Date(2010, 0, 1, 0, 0, 0, 0); // Start of 2010.


var utc_a = new Date(a.toUTCString());
var utc_b = new Date(b.toUTCString());
var diff = (utc_b - utc_a); // The difference as milliseconds.

Then to work out the number of seconds in that difference, divide it by 1000 to convert
milliseconds to seconds, then change the result to an integer (whole number) to remove
the milliseconds (fraction part of that decimal): var seconds = parseInt(diff/1000).
Also, I could get longer units of time using the same process, for example:
- (whole) minutes, dividing seconds by 60 and changing the result to an integer,
- hours, dividing minutes by 60 and changing the result to an integer.

I created a function for doing that process of splitting the difference into
whole units of time, named split_to_whole_units, with this demo:

console.log(split_to_whole_units(72000, [1000, 60]));
// -> [1,12,0] # 1 (whole) minute, 12 seconds, 0 milliseconds.

This answer is based on this other one.

You can also use it

export function diffDateAndToString(small: Date, big: Date) {




// To calculate the time difference of two dates
const Difference_In_Time = big.getTime() - small.getTime()


// To calculate the no. of days between two dates
const Days = Difference_In_Time / (1000 * 3600 * 24)
const Mins = Difference_In_Time / (60 * 1000)
const Hours = Mins / 60


const diffDate = new Date(Difference_In_Time)


console.log({ date: small, now: big, diffDate, Difference_In_Days: Days, Difference_In_Mins: Mins, Difference_In_Hours: Hours })


var result = ''


if (Mins < 60) {
result = Mins + 'm'
} else if (Hours < 24) result = diffDate.getMinutes() + 'h'
else result = Days + 'd'
return { result, Days, Mins, Hours }
}

results in { result: '30d', Days: 30, Mins: 43200, Hours: 720 }