Javascript 返回两个日期之间的天数,小时,分钟,秒数

是否有人可以链接到一些教程,我可以找到如何返回天,小时,分钟,秒在 javascript 之间的2 Unix 日期时间?

我有:

var date_now = unixtimestamp;
var date_future = unixtimestamp;

我想返回(生活)多少天,小时,分钟,秒从日期现在到日期未来。

216832 次浏览

Please note that calculating only based on differences will not cover all cases: leap years and switching of "daylight savings time".

Javascript has poor built-in library for working with dates. I suggest you use a third party javascript library, e.g. MomentJS; you can see here the function you were looking for.

Just figure out the difference in seconds (don't forget JS timestamps are actually measured in milliseconds) and decompose that value:

// get total seconds between the times
var delta = Math.abs(date_future - date_now) / 1000;


// calculate (and subtract) whole days
var days = Math.floor(delta / 86400);
delta -= days * 86400;


// calculate (and subtract) whole hours
var hours = Math.floor(delta / 3600) % 24;
delta -= hours * 3600;


// calculate (and subtract) whole minutes
var minutes = Math.floor(delta / 60) % 60;
delta -= minutes * 60;


// what's left is seconds
var seconds = delta % 60;  // in theory the modulus is not required

EDIT code adjusted because I just realised that the original code returned the total number of hours, etc, not the number of hours left after counting whole days.

Here's in javascript: (For example, the future date is New Year's Day)

DEMO (updates every second)

var dateFuture = new Date(new Date().getFullYear() +1, 0, 1);
var dateNow = new Date();


var seconds = Math.floor((dateFuture - (dateNow))/1000);
var minutes = Math.floor(seconds/60);
var hours = Math.floor(minutes/60);
var days = Math.floor(hours/24);


hours = hours-(days*24);
minutes = minutes-(days*24*60)-(hours*60);
seconds = seconds-(days*24*60*60)-(hours*60*60)-(minutes*60);

The best library that I know of for duration breakdown is countdown.js. It handles all the hard cases such as leap years and daylight savings as csg mentioned, and even allows you to specify fuzzy concepts such as months and weeks. Here's the code for your case:

//assuming these are in *seconds* (in case of MS don't multiply by 1000 below)
var date_now = 1218374;
var date_future = 29384744;


diff = countdown(date_now * 1000, date_future * 1000,
countdown.DAYS | countdown.HOURS | countdown.MINUTES | countdown.SECONDS);
alert("days: " + diff.days + " hours: " + diff.hours +
" minutes: " + diff.minutes + " seconds: " + diff.seconds);


//or even better
alert(diff.toString());

Here's a JSFiddle, but it would probably only work in FireFox or in Chrome with web security disabled, since countdown.js is hosted with a text/plain MIME type (you're supposed to serve the file, not link to countdownjs.org).

I call it the "snowman ☃ method" and I think it's a little more flexible when you need additional timespans like weeks, moths, years, centuries... and don't want too much repetitive code:

var d = Math.abs(date_future - date_now) / 1000;                           // delta
var r = {};                                                                // result
var s = {                                                                  // structure
year: 31536000,
month: 2592000,
week: 604800, // uncomment row to ignore
day: 86400,   // feel free to add your own row
hour: 3600,
minute: 60,
second: 1
};


Object.keys(s).forEach(function(key){
r[key] = Math.floor(d / s[key]);
d -= r[key] * s[key];
});


// for example: {year:0,month:0,week:1,day:2,hour:34,minute:56,second:7}
console.log(r);

Have a FIDDLE / ES6 Version (2018) / TypeScript Version (2019)

Inspired by Alnitak's answer.

function update(datetime = "2017-01-01 05:11:58") {
var theevent = new Date(datetime);
now = new Date();
var sec_num = (theevent - now) / 1000;
var days    = Math.floor(sec_num / (3600 * 24));
var hours   = Math.floor((sec_num - (days * (3600 * 24)))/3600);
var minutes = Math.floor((sec_num - (days * (3600 * 24)) - (hours * 3600)) / 60);
var seconds = Math.floor(sec_num - (days * (3600 * 24)) - (hours * 3600) - (minutes * 60));


if (hours   < 10) {hours   = "0"+hours;}
if (minutes < 10) {minutes = "0"+minutes;}
if (seconds < 10) {seconds = "0"+seconds;}


return  days+':'+ hours+':'+minutes+':'+seconds;
}

Here is a code example. I used simple calculations instead of using precalculations like 1 day is 86400 seconds. So you can follow the logic with ease.

// Calculate time between two dates:
var date1 = new Date('1110-01-01 11:10');
var date2 = new Date();


console.log('difference in ms', date1 - date2);


// Use Math.abs() so the order of the dates can be ignored and you won't
// end up with negative numbers when date1 is before date2.
console.log('difference in ms abs', Math.abs(date1 - date2));
console.log('difference in seconds', Math.abs(date1 - date2) / 1000);


var diffInSeconds = Math.abs(date1 - date2) / 1000;
var days = Math.floor(diffInSeconds / 60 / 60 / 24);
var hours = Math.floor(diffInSeconds / 60 / 60 % 24);
var minutes = Math.floor(diffInSeconds / 60 % 60);
var seconds = Math.floor(diffInSeconds % 60);
var milliseconds = Math.round((diffInSeconds - Math.floor(diffInSeconds)) * 1000);


console.log('days', days);
console.log('hours', ('0' + hours).slice(-2));
console.log('minutes', ('0' + minutes).slice(-2));
console.log('seconds', ('0' + seconds).slice(-2));
console.log('milliseconds', ('00' + milliseconds).slice(-3));

here is an code to find difference between two dates in Days,Hours,Minutes,Seconds (assuming the future date is new year date).

var one_day = 24*60*60*1000;              // total milliseconds in one day


var today = new Date();
var new_year = new Date("01/01/2017");    // future date


var today_time = today.getTime();         // time in miliiseconds
var new_year_time = new_year.getTime();


var time_diff = Math.abs(new_year_time - today_time);  //time diff in ms
var days = Math.floor(time_diff / one_day);            // no of days


var remaining_time = time_diff - (days*one_day);      // remaining ms


var hours = Math.floor(remaining_time/(60*60*1000));
remaining_time = remaining_time - (hours*60*60*1000);


var minutes = Math.floor(remaining_time/(60*1000));
remaining_time = remaining_time - (minutes * 60 * 1000);


var seconds = Math.ceil(remaining_time / 1000);

Use moment.js library, for example:

var time = date_future - date_now;
var seconds = moment.duration(time).seconds();
var minutes = moment.duration(time).minutes();
var hours   = moment.duration(time).hours();
var days    = moment.duration(time).days();
let delta = Math.floor(Math.abs(start.getTime() - end.getTime()) / 1000);
let hours = Math.floor(delta / 3600);
delta -= hours * 3600;
let minutes = Math.floor(delta / 60);
delta -= minutes * 60;
let seconds = delta;
if (hours.toString().length === 1) {
hours = `0${hours}`;
}
if (minutes.toString().length === 1) {
minutes = `0${minutes}`;
}
if (seconds.toString().length === 1) {
seconds = `0${seconds}`;
}
const recordingTime = `${hours}:${minutes}:${seconds}`;

Short and flexible with support for negative values, although by using two comma expressions :)

function timeUnitsBetween(startDate, endDate) {
let delta = Math.abs(endDate - startDate) / 1000;
const isNegative = startDate > endDate ? -1 : 1;
return [
['days', 24 * 60 * 60],
['hours', 60 * 60],
['minutes', 60],
['seconds', 1]
].reduce((acc, [key, value]) => (acc[key] = Math.floor(delta / value) * isNegative, delta -= acc[key] * isNegative * value, acc), {});
}

Example:

timeUnitsBetween(new Date("2019-02-11T02:12:03+00:00"), new Date("2019-02-11T01:00:00+00:00"));
// { days: -0, hours: -1, minutes: -12, seconds: -3 }

Inspired by RienNeVaPlu͢s solution.

MomentJS has a function to do that:

const start = moment(j.timings.start);
const end = moment(j.timings.end);
const elapsedMinutes = end.diff(start, "minutes");

my solution is not as clear as that, but I put it as another example

console.log(duration('2019-07-17T18:35:25.235Z', '2019-07-20T00:37:28.839Z'));


function duration(t0, t1){
let d = (new Date(t1)) - (new Date(t0));
let weekdays     = Math.floor(d/1000/60/60/24/7);
let days         = Math.floor(d/1000/60/60/24 - weekdays*7);
let hours        = Math.floor(d/1000/60/60    - weekdays*7*24            - days*24);
let minutes      = Math.floor(d/1000/60       - weekdays*7*24*60         - days*24*60         - hours*60);
let seconds      = Math.floor(d/1000          - weekdays*7*24*60*60      - days*24*60*60      - hours*60*60      - minutes*60);
let milliseconds = Math.floor(d               - weekdays*7*24*60*60*1000 - days*24*60*60*1000 - hours*60*60*1000 - minutes*60*1000 - seconds*1000);
let t = {};
['weekdays', 'days', 'hours', 'minutes', 'seconds', 'milliseconds'].forEach(q=>{ if (eval(q)>0) { t[q] = eval(q); } });
return t;
}

Here's my take:

timeSince(123456) => "1 day, 10 hours, 17 minutes, 36 seconds"

And the code:

function timeSince(date, longText) {
let seconds = null;
let leadingText = null;


if (date instanceof Date) {
seconds = Math.floor((new Date() - date) / 1000);
if (seconds < 0) {
leadingText = " from now";
} else {
leadingText = " ago";
}
seconds = Math.abs(seconds);
} else {
seconds = date;
leadingText = "";
}


const intervals = [
[31536000, "year"  ],
[ 2592000, "month" ],
[   86400, "day"   ],
[    3600, "hour"  ],
[      60, "minute"],
[       1, "second"],
];


let interval = seconds;
let intervalStrings = [];
for (let i = 0; i < intervals.length; i++) {
let divResult = Math.floor(interval / intervals[i][0]);
if (divResult > 0) {
intervalStrings.push(divResult + " " + intervals[i][1] + ((divResult > 1) ? "s" : ""));
interval = interval % intervals[i][0];
if (!longText) {
break;
}
}
}
let intStr = intervalStrings.join(", ");


return intStr + leadingText;
}

Easy Way

function diff_hours(dt2, dt1)
{


var diff =(dt2.getTime() - dt1.getTime()) / 1000;
diff /= (60 * 60);
return Math.abs(Math.round(diff));


}




function diff_minutes(dt2, dt1)
{


var diff =(dt2.getTime() - dt1.getTime()) / 1000;
diff /= (60);
return Math.abs(Math.round(diff));


}


function diff_seconds(dt2, dt1)
{


var diff =(dt2.getTime() - dt1.getTime()) / 1000;
return Math.abs(Math.round(diff));


}


function diff_miliseconds(dt2, dt1)
{


var diff =(dt2.getTime() - dt1.getTime());
return Math.abs(Math.round(diff));


}




dt1 = new Date(2014,10,2);
dt2 = new Date(2014,10,3);
console.log(diff_hours(dt1, dt2));




dt1 = new Date("October 13, 2014 08:11:00");
dt2 = new Date("October 14, 2014 11:13:00");
console.log(diff_hours(dt1, dt2));


console.log(diff_minutes(dt1, dt2));


console.log(diff_seconds(dt1, dt2));


console.log(diff_miliseconds(dt1, dt2));
function calculateExamRemainingTime(exam_end_at) {


$(function(){


const calcNewYear = setInterval(function(){


const exam_ending_at    = new Date(exam_end_at);
const current_time      = new Date();
       

const totalSeconds     = Math.floor((exam_ending_at - (current_time))/1000);;
const totalMinutes     = Math.floor(totalSeconds/60);
const totalHours       = Math.floor(totalMinutes/60);
const totalDays        = Math.floor(totalHours/24);


const hours   = totalHours - ( totalDays * 24 );
const minutes = totalMinutes - ( totalDays * 24 * 60 ) - ( hours * 60 );
const seconds = totalSeconds - ( totalDays * 24 * 60 * 60 ) - ( hours * 60 * 60 ) - ( minutes * 60 );


const examRemainingHoursSection = document.querySelector('#remainingHours');
const examRemainingMinutesSection = document.querySelector('#remainingMinutes');
const examRemainingSecondsSection = document.querySelector('#remainingSeconds');


examRemainingHoursSection.innerHTML = hours.toString();
examRemainingMinutesSection.innerHTML = minutes.toString();
examRemainingSecondsSection.innerHTML = seconds.toString();


},1000);
});
}


calculateExamRemainingTime('2025-06-03 20:20:20');

We can do it by simple method

/*Declare the function */
function Clock(){
let d1 = new Date("1 Jan 2021");
let d2 = new Date();


let difference = Math.abs(d1 - d2); //to get absolute value
//calculate for each one
let Days = Math.floor(difference / ( 1000 * 60 * 60 * 24 ));
let Hours = Math.floor((difference / ( 1000 * 60 * 60 )) % 24);
let Mins = Math.floor((difference / ( 1000 * 60 )) % 60);
let Seconds = Math.floor((difference / ( 1000 )) % 60);


//getting nodes and change the text inside
let getday = document.querySelector(".big_text_days");
let gethour = document.querySelector(".big_text_hours");
let getmins = document.querySelector(".big_text_mins");
let getsec = document.querySelector(".big_text_sec");


getday.textContent = Check_Zero(Days);
gethour.textContent = Check_Zero(Hours);
getmins.textContent = Check_Zero(Mins)
getsec.textContent = Check_Zero(Seconds);
}


//call the funcion for every 1 second
setInterval(Clock , 1000);




//check and add zero in front, if it is lessthan 10
function Check_Zero(mytime){
return mytime < 10 ? "0"+mytime : mytime;


}
*{
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
body{
max-width: 900px;
margin: 0px auto;
background-color:whitesmoke;
background-size: cover;
display: flex;
flex-direction: column;
align-items: center;
margin-top: 5rem;
}
.main_container{
display: flex;
flex-wrap: wrap;
justify-content: center;
}
h1{
font-size: 3rem;
color: #3D4B72;
}
.big_text_days , .big_text_hours , .big_text_mins , .big_text_sec{
font-size: 2rem;
font-weight: bold;
line-height: 2;
color: #AC7591;
text-align: center;
}
p{
padding: 20px 0px 20px 0px;
font-size: 3rem;
text-align: center;
}
.spantext{
color: #103c28;
margin: 0px 3rem;
font-size: 2rem;
font-style: italic;
}
.text_sec{
color : #005259;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="description" content="Responsive site">
<meta name="keywords" content="HTML,CSS,JS">
<meta name="author" content="Ranjan">
<meta name="viewport" content="width=device-width, initial-scale=1.0">


<title>Home</title>


<link href="https://fonts.googleapis.com/css?family=Alfa+Slab+One|Bree+Serif|Exo|Exo+2|Lato|Mansalva|Playfair+Display&display=swap" rel="stylesheet">
       

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">


</head>


<body>
        

<section>
<h1>CountDown Timer</h1>
</section>
                

<section>
<div class="main_container">
                

<div class="days_container">
<p class="big_text_days">1</p>
<span class="spantext spantextdays">Days</span>
</div>
    

<div class="hours_container">
<p class="big_text_hours">1</p>
<span class="spantext spantexthours">Hours</span>
</div>
    

<div class="mins_container">
<p class="big_text_mins">1</p>
<span class="spantext spantextmins">Minutes</span>
</div>
            

<div class="sec_container">
<p class="big_text_sec text_sec">1</p>
<span class="spantext spantextsec">Seconds</span>
</div>
</div>
</section>


</body>
</html>

const arrDiff = [
{
label: 'second',
value: 1000,
},
{
label: 'minute',
value: 1000 * 60,
},
{
label: 'hour',
value: 1000 * 60 * 60,
},
{
label: 'day',
value: 1000 * 60 * 60 * 24,
},
{
label: 'year',
value: 1000 * 60 * 60 * 24 * 365,
},
];


function diff(date) {
let result = { label: '', value: '' };
const value = Date.now() - date;
for (let obj of arrDiff) {
let temp = Math.round(value / obj.value);
if (temp === 0) {
break;
} else
result = {
value: temp,
label: obj.label,
};
}
return result;
}


const postDate = new Date('2020-12-17 23:50:00+0700');
console.log(diff(postDate));

Because MomentJS is quite heavy and sub-optimized, people not afraid to use a module should probably look at date-fns instead, which provides an intervalToDuration method which does what you want:

const result = intervalToDuration({
start: new Date(dateNow),
end: new Date(dateFuture),
})

And which would return an object looking like so:

{
years: 39,
months: 2,
days: 20,
hours: 7,
minutes: 5,
seconds: 0,
}

Then you can even use formatDuration to display this object as a string using the parameters you prefer

2021 version

Inspired with Alnitak's and RienNeVaPlus's answers.

Calculates since and until automatically (see examples below).

const timeUnits = {
year: 31536e6,
month: 2592e6,
week: 6048e5,
day: 864e5,
hour: 36e5,
minute: 6e4,
second: 1e3,
};


const timeUnitsNamesShort = {
year: 'y',
month: 'm',
week: 'w',
day: 'd',
hour: 'h',
minute: 'm',
second: 's',
};


const isFuture = (date) => date > Date.now();


const dateDiffStructure = (date, units = timeUnits) => {
let delta = Math.abs(date - Date.now());
return Object.entries(units).reduce((acc, [key, value]) => {
acc[key] = Math.floor(delta / value);
delta -= acc[key] * value;
return acc;
}, {});
};


const dateDiffStructureToString = (date, diffStructure, values, short) => {
const diffStructureEntries = values
? Object.entries(diffStructure).filter(([key, value]) => values.includes(key) && value)
: Object.entries(diffStructure).filter(([, value]) => value);
if (!diffStructureEntries.length) return 'just now';
const suffix = isFuture(date) ? 'left' : 'ago';
const diffString = diffStructureEntries.reduce((acc, [key, value]) => {
const timeUnit = short
? timeUnitsNamesShort[key]
: value > 1
? ` ${key}s`
: ` ${key}`;
acc = acc ? `${acc} ` : '';
return `${acc}${value}${timeUnit}`;
}, '');
return `${diffString} ${suffix}`;
};


const getDateDiff = (date, values, short) => {
const diffStructure = dateDiffStructure(date);
return dateDiffStructureToString(date, diffStructure, values, short);
};

Tests and examples:

const timeUnits = {
year: 31536e6,
month: 2592e6,
week: 6048e5,
day: 864e5,
hour: 36e5,
minute: 6e4,
second: 1e3,
};


const timeUnitsNamesShort = {
year: 'y',
month: 'm',
week: 'w',
day: 'd',
hour: 'h',
minute: 'm',
second: 's',
};


const isFuture = (date) => date > Date.now();


const dateDiffStructure = (date, units = timeUnits) => {
let delta = Math.abs(date - Date.now());
return Object.entries(units).reduce((acc, [key, value]) => {
acc[key] = Math.floor(delta / value);
delta -= acc[key] * value;
return acc;
}, {});
};


const dateDiffStructureToString = (date, diffStructure, values, short) => {
const diffStructureEntries = values ?
Object.entries(diffStructure).filter(([key, value]) => values.includes(key) && value) :
Object.entries(diffStructure).filter(([, value]) => value);
if (!diffStructureEntries.length) return 'just now';
const suffix = isFuture(date) ? 'left' : 'ago';
const diffString = diffStructureEntries.reduce((acc, [key, value]) => {
const timeUnit = short ?
timeUnitsNamesShort[key] :
value > 1 ?
` ${key}s` :
` ${key}`;
acc = acc ? `${acc} ` : '';
return `${acc}${value}${timeUnit}`;
}, '');
return `${diffString} ${suffix}`;
};


const getDateDiff = (date, values, short) => {
const diffStructure = dateDiffStructure(date);
console.log(`dateDiffStructure(${JSON.stringify(date)}) //`, diffStructure);
return dateDiffStructureToString(date, diffStructure, values, short);
};


const tests = [
['After tomorrow', [new Date(Date.now() + 8.64e7 + 1e6)]],
['Yesterday', [new Date(Date.now() - 8.64e7)]],
['Past', [new Date(Date.now() * Math.random())]],
['Future short', [new Date(Date.now() * (Math.random() + 1)), ['year', 'month', 'day'], true]],
['Now', [Date.now()]]
];


tests.forEach(([text, args]) => {
console.log(`${text}:`);
console.group();
console.log(`getDateDiff(${args.map(item => JSON.stringify(item)).join(', ')}) //`, getDateDiff(...args));
console.groupEnd();
});

For those who wants only hours and minutes use this

const oldDate = new Date("2021-04-28T13:17:31.000Z")
const newDate = new Date("2021-04-28T22:08:07.000Z")
const msToTime = (ms) => ({
hours: Math.trunc(ms/3600000),
minutes: Math.trunc((ms/3600000 - Math.trunc(ms/3600000))*60) + ((ms/3600000 - Math.trunc(ms/3600000))*60 % 1 != 0 ? 1 : 0)
})


console.log(msToTime(Math.abs(newDate-oldDate)))

A Little bit different flavour (maybe for some ppl more readable) it works in JavaScript and as little bonus it works in TypeScript as well.

If you make sure the first date is always greater than the second than you don't need the Math.abs() Also the round brackets around the modulo operation are unnecessary. I kept them for clearance.

let diffTime = Math.abs(new Date().valueOf() - new Date('2021-11-22T18:30:00').valueOf());
let days = diffTime / (24*60*60*1000);
let hours = (days % 1) * 24;
let minutes = (hours % 1) * 60;
let secs = (minutes % 1) * 60;
[days, hours, minutes, secs] = [Math.floor(days), Math.floor(hours), Math.floor(minutes), Math.floor(secs)]


console.log(days+'d', hours+'h', minutes+'m', secs+'s');

function getTimeRemaining(endtime){
const total = Date.parse(endtime) - Date.parse(new Date());
const seconds = Math.floor( (total/1000) % 60 );
const minutes = Math.floor( (total/1000/60) % 60 );
const hours = Math.floor( (total/(1000*60*60)) % 24 );
const days = Math.floor( total/(1000*60*60*24) );


return {
total,
days,
hours,
minutes,
seconds
};
}


let result = getTimeRemaining(endTime) // pass the end date into the func

you can also find out the diff between two dates time by easily change the func parameters to


function getTimeRemaining(endtime,startime){
const total = Date.parse(endtime) - Date.parse(startime);
const seconds = Math.floor( (total/1000) % 60 );
const minutes = Math.floor( (total/1000/60) % 60 );
const hours = Math.floor( (total/(1000*60*60)) % 24 );
const days = Math.floor( total/(1000*60*60*24) );


return {
total,
days,
hours,
minutes,
seconds
};
}


let result = getTimeRemaining(endTime,startTime)


The result will be like

days: 0, hours: 1, minutes: 0, seconds: 0, total: 3600000

Here’s that answer in TypeScript without mutation. Also has a 2-digit seconds handler.

const maybeAddLeadingZero = (number: number): string => [String(number).length === 1 ? '0' : '', number].join('');


const timeRemaining = (endDate: Date): string => {
const deltaInSeconds = Math.abs(Date.now() - endDate.valueOf()) / 1000;


const days = Math.floor(deltaInSeconds / 86400);
const deltaMinusDaysInSeconds = deltaInSeconds - days * 86400;


const hours = Math.floor(deltaMinusDaysInSeconds / 3600) % 24;
const deltaMinusHoursInSeconds = deltaMinusDaysInSeconds - hours * 3600;


const minutes = Math.floor(deltaMinusHoursInSeconds / 60) % 60;
const twoDigitMinutes = maybeAddLeadingZero(minutes);
const deltaMinusMinutesInSeconds = deltaMinusHoursInSeconds - minutes * 60;


const seconds = Math.floor(deltaMinusMinutesInSeconds % 60);
const twoDigitSeconds = maybeAddLeadingZero(seconds);


return `${hours}:${twoDigitMinutes}:${twoDigitSeconds}`
}


const twentyFourHoursInTheFuture = new Date(new Date().getTime() + 24 * 60 * 60 * 1000)


// example implementation
setInterval(() => {
const deriveTimeRemaining = timeRemaining(twentyFourHoursInTheFuture);


document.body.innerHTML = "";
document.write(`<h1>${deriveTimeRemaining}</h1>`)
}, 1000 / 60) // 60 FPS