Reputation: 135
I need to calculate the duration between two datetimes in JavaScript. I have tried this code:
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
if(dd<10){dd='0'+dd} if(mm<10){mm='0'+mm} today = mm+'/'+dd+'/'+yyyy; //Current Date
console.log("current date"+today);
var valuestart ="8:00 AM";
var valuestop = "4:00 PM";//$("select[name='timestop']").val();
//create date format
var timeStart = new Date("01/01/2007 " + valuestart).getHours();
var timeEnd = new Date("01/01/2007 " + valuestop).getHours();
var hourDiff = timeEnd - timeStart;
console.log("duration"+hourDiff);
From this, I am able to get Current Date and duration. But when I replace the date "01/01/2007" with the variable "today", I am getting the result as NaN. Please guide me in where I am wrong. Thanks in advance.
Upvotes: 6
Views: 27242
Reputation: 2855
If your duration is guaranteed to be less than 24 hours and you want to display it to the user here is a very simple solution:
function formatDuration(millis) {
return new Date(millis).toISOString().substring(11, 19);
}
console.log(formatDuration(59999)); // 00:00:59
console.log(formatDuration(3599999)); // 00:59:59
console.log(formatDuration(86399999)); // 23:59:59
function formatDuration(millis) {
let date = new Date(millis);
let parts = [];
if (date.getUTCFullYear() > 1970) {
let years = date.getUTCFullYear() - 1970;
parts.push(years, pluralize(years, 'year'));
}
if (date.getUTCMonth() > 0) { // months start at zero
let months = date.getUTCMonth();
parts.push(months, pluralize(months, 'month'));
}
if (date.getUTCDate() > 1) {
let days = date.getUTCDate() - 1;
parts.push(days, pluralize(days, 'day'));
}
parts.push(date.toISOString().substring(11, 19));
return parts.join(' ');
}
function pluralize(count, singular, plural) {
return count === 1 ? singular : plural ?? `${singular}s`;
}
console.log(formatDuration(new Date('1970-01-01T00:00:59.999Z').getTime())); // 00:00:59
console.log(formatDuration(new Date('1970-01-01T00:59:59.999Z').getTime())); // 00:59:59
console.log(formatDuration(new Date('1970-01-01T23:59:59.999Z').getTime())); // 23:59:59
console.log(formatDuration(new Date('1970-01-31T23:59:59.999Z').getTime())); // 30 days 23:59:59
console.log(formatDuration(new Date('1970-12-01T23:59:59.999Z').getTime())); // 11 months 23:59:59
console.log(formatDuration(new Date('1970-12-31T23:59:59.999Z').getTime())); // 11 months 30 days 23:59:59
console.log(formatDuration(new Date('1971-01-01T23:59:59.999Z').getTime())); // 1 year 23:59:59
console.log(formatDuration(new Date('1971-01-31T23:59:59.999Z').getTime())); // 1 year 30 days 23:59:59
console.log(formatDuration(new Date('1971-12-01T23:59:59.999Z').getTime())); // 1 year 11 months 23:59:59
console.log(formatDuration(new Date('1971-12-31T23:59:59.999Z').getTime())); // 1 year 11 months 30 days 23:59:59
If you want to include the milliseconds use this substring instead:
.substring(11, 23) // 23:59:59.999
and for completeness the JSDoc:
/**
* Formats a number of milliseconds to `HH:mm:ss`.
* For durations of 24h and longer, prefixes the number of years, months, days if any are at least 1.
* Examples:
* * `00:00:59`
* * `00:59:59`
* * `23:59:59`
* * `30 days 23:59:59`
* * `11 months 23:59:59`
* * `11 months 30 days 23:59:59`
* * `1 year 23:59:59`
* * `1 year 30 days 23:59:59`
* * `1 year 11 months 23:59:59`
* * `1 year 11 months 30 days 23:59:59`
* @param {number} millis milliseconds
* @return {string} the time portion in ISO format (excluding milliseconds) i.e. 23:59:59
*/
Upvotes: 0
Reputation: 7585
I tried luxon
and it's very handy:
Given dt1
and dt2
as ISO representation of date time,
luxon.DateTime.fromISO(dt1).diff(
luxon.DateTime.fromISO(dt2),
['years', 'months', 'days', 'hours', 'minutes', 'seconds']
).values
Upvotes: 0
Reputation: 1
Maybe It's a little bit late. I second the answer from Christophe Roussy. First, calculate the difference in UTC format, then turn the unit - hour. I think it's easier to understand and maintain. Here's the code
var date1 = new Date(`some_valid_start_date_format`);
var date2 = new Date(`some_end_start_date_format`);
var duration = date2.valueOf() - date1.valueOf(); // The unit is millisecond
var hourDiff = parseInt(duration / (60 * 60 * 1000)) // Turn the duration into hour format
Upvotes: 0
Reputation: 1548
Try this :
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
if(dd<10){dd='0'+dd} if(mm<10){mm='0'+mm} today = dd+'/'+mm+'/'+yyyy; //Current Date
var valuestart ="8:00 AM";
var valuestop = "4:00 PM";//$("select[name='timestop']").val();
//create date format
var timeStart = new Date(today + " " + valuestart).getHours();
var timeEnd = new Date(today + " " + valuestop).getHours();
var hourDiff = timeEnd - timeStart;
alert("duration:"+hourDiff);
Upvotes: 2
Reputation: 17049
You should work on the epoch milliseconds. The idea is to transform everything to the epoch millis representation, perform your calculations, then go back to another format if needed.
There are many articles on the subject:
Upvotes: 3
Reputation: 5984
today is of Date type whereas "01/01/2007" is a string. Trying to concatenate a Date object with "8:00 AM" will not work. You will have to turn today variable into a string or use today.setHours(8)
Upvotes: 1