Home
IT Knowledge
Inspiration
Languages
EN

JavaScript - how to calculate time period (time difference in days, minutes, seconds and milliseconds)?

2 points
Created by:
28450

In this article, we're going to have a look at how to calculate time between two dates in JavaScript.

First thing that we should mention is fact the number of days in different months and years is different so the easiest way is to express it is number of days, hours, minutes, seconds and milliseconds.

1. Custom time period example

In this section dates are converted to milliseconds difference. Basing on the difference we are able in simple way to calculate amount of days, hours, minutes, etc.

``````// ONLINE-RUNNER:browser;

var units = [
{name: 'milliseconds', scale: 1000},
{name: 'seconds', scale: 60},
{name: 'minutes', scale: 60},
{name: 'hours', scale: 24}
];

// calculates difference between dates
function calculatePeriod(t1, t2) {
var dt = t2 - t1;
var result = { };
for(var i = 0; i < units.length; ++i) {
var unit = units[i];
var total = Math.floor(dt / unit.scale);
var rest = dt - total * unit.scale;
result[unit.name] = rest;
dt = total;
}
result.days = dt;
return result;
}

// calculates difference between dates and creates string
function renderPeriod(t1, t2) {
var period = calculatePeriod(t1, t2);
var result = '';
if (value) {
if (result) {
result += ' ';
}
result += value + ' ' + (value === 1 ? unit : unit + 's');
}
}
return result || 'dates are same';
}

// Usage example:

var t0 = new Date(2000, 0, 1);                    // 1 January 2000, 00:00:00.000

var t1 = new Date(2000,  0, 1);                   // 1 January 2000, 00:00:00.000
var t2 = new Date(2000,  0, 1,  0,  0,  0, 999);  // 1 January 2000, 00:00:00.999
var t3 = new Date(2000,  0, 1,  0,  0, 30, 999);  // 1 January 2000, 00:00:30.999
var t4 = new Date(2000,  0, 1,  0, 10, 30, 999);  // 1 January 2000, 00:10:30.999
var t5 = new Date(2000,  0, 1, 15, 10, 30, 999);  // 1 January 2000, 15:10:30.999
var t6 = new Date(2000,  0, 5, 15, 10, 30, 999);  // 5 January 2000, 15:10:30.999
var t7 = new Date(2000, 10, 5, 15, 10, 30, 999);  // 5 November 2000, 15:10:30.999
var t8 = new Date(2015, 10, 5, 15, 10, 30, 999);  // 5 November 2015, 15:10:30.999
var t9 = new Date();                              // current date and time

console.log(renderPeriod(t0, t1));  // dates are same
console.log(renderPeriod(t0, t2));  // 999 milliseconds
console.log(renderPeriod(t0, t3));  // 30 seconds 999 milliseconds
console.log(renderPeriod(t0, t4));  // 10 minutes 30 seconds 999 milliseconds
console.log(renderPeriod(t0, t5));  // 15 hours 10 minutes 30 seconds 999 milliseconds
console.log(renderPeriod(t0, t6));  // 4 days 15 hours 10 minutes 30 seconds 999 milliseconds
console.log(renderPeriod(t0, t7));  // 309 days 15 hours 10 minutes 30 seconds 999 milliseconds
console.log(renderPeriod(t0, t8));  // 5787 days 15 hours 10 minutes 30 seconds 999 milliseconds
console.log(renderPeriod(t0, t9));  // <current_date_and_time> - t0``````

2. Alternative implementation example

This approach allows to:

• render string with indicated amount of parts (e.g. 2 parts `10s 30min`) ,
• use custom units (`labels` array as last argument),
• select message to display when precision of labels is not enought (e.g. `done` variable can be set as `'Now'` when we want to say comment was posted now - not 100ms ago).

Note:

• this approach is not perfect because of different days per one year, but for displaying aproximate period time it is enought (e.g. comments system),
• to solve the problem we can remove years part from code.
``````// ONLINE-RUNNER:browser;

var TimeUtils = new function() {

var UNITS = [
{name: 'milliseconds', scale: 1000},
{name: 'seconds',      scale: 60},
{name: 'minutes',      scale: 60},
{name: 'hours',        scale: 24},
{name: 'days',         scale: 30},
{name: 'months',       scale: 12}
];
var LABELS = [
{name: 'years',   unit: 'y'},
{name: 'months',  unit: 'm'},
{name: 'days',    unit: 'd'},
{name: 'hours',   unit: 'h'},
{name: 'minutes', unit: 'min'},
{name: 'seconds', unit: 's'}
];

var self = this;

function renderPart(period, label) {
var value = period[label.name];
if (value) {
return value + label.unit;
}
return null;
}

self.calculatePeriod = function(t1, t2, units) {
if(units == null) {
units = UNITS;
}
var dt = t2 - t1;
var result = { };
for(var i = 0; i < units.length; ++i) {
var unit = units[i];
var total = Math.floor(dt / unit.scale);
var rest = dt - total * unit.scale;
result[unit.name] = rest;
dt = total;
}
result.years = dt;
return result;
};

// Renders period (timespan / moment) string.
//
// period - rendered period
// done - returned string when period is smaller than labels precision
// size - number or rendered parts (for 2 renders '[value1][unit2] [value2][unit2]')
// labels - array of own custom labels
//
self.renderPeriod\$1 = function(period, done, size, labels) {
if (labels == null) {
labels = LABELS;
}
if (size == null) {
size = 2;
}
var result = '';
for (var i = 0; i < labels.length && size > 0; ++i) {
var part = renderPart(period, labels[i]);
if (part) {
if (result) {
result += ' ';
}
size -= 1;
result += part;
} else {
if (result) {
break;
}
}
}
return result || done || '0ms';
};

// Renders period (timespan / moment) string for difference between current system time and t2.
//
// time - time of event
// done - returned string when period is smaller than labels precision
// size - number or rendered parts (for 2 renders '[value1][unit2] [value2][unit2]')
// labels - array of own custom labels
//
self.renderPeriod\$2 = function(time, done, size, labels) {
var now = self.getTime();
return self.renderPeriod\$2(time, now, done, size, labels);
};

// Renders period (timespan / moment) string for difference between t1 and t2.
//
// t1 - start time
// t2 - end time
// done - returned string when period is smaller than labels precision
// size - number or rendered parts (for 2 renders '[value1][unit2] [value2][unit2]')
// labels - array of own custom labels
//
self.renderPeriod\$3 = function(t1, t2, done, size, labels) {
var period = self.calculatePeriod(t1, t2);
return self.renderPeriod\$1(period, done, size, labels);
};
};

// Usage example 1:

//                                   t1            t2
console.log(TimeUtils.renderPeriod\$3(0,                       1000));  // 1s
console.log(TimeUtils.renderPeriod\$3(0,                  30 * 1000));  // 30s
console.log(TimeUtils.renderPeriod\$3(0, 10 * 60 * 1000 + 30 * 1000));  // 10min 30s

// Usage example 2:

var t0 = new Date(2000, 0, 1);                    // 1 January 2000, 00:00:00.000

var t1 = new Date(2000,  0, 1);                   // 1 January 2000, 00:00:00.000
var t2 = new Date(2000,  0, 1,  0,  0,  0, 999);  // 1 January 2000, 00:00:00.999
var t3 = new Date(2000,  0, 1,  0,  0, 30, 999);  // 1 January 2000, 00:00:30.999
var t4 = new Date(2000,  0, 1,  0, 10, 30, 999);  // 1 January 2000, 00:10:30.999
var t5 = new Date(2000,  0, 1, 15, 10, 30, 999);  // 1 January 2000, 15:10:30.999
var t6 = new Date(2000,  0, 5, 15, 10, 30, 999);  // 5 January 2000, 15:10:30.999
var t7 = new Date(2000, 10, 5, 15, 10, 30, 999);  // 5 November 2000, 15:10:30.999
var t8 = new Date(2015, 10, 5, 15, 10, 30, 999);  // 5 November 2015, 15:10:30.999
var t9 = new Date();                              // current date and time

console.log(TimeUtils.renderPeriod\$3(t0, t1, 'Now'  ));  // Now
console.log(TimeUtils.renderPeriod\$3(t0, t2, '0'    ));  // 0
console.log(TimeUtils.renderPeriod\$3(t0, t3, null, 5));  // 30s
console.log(TimeUtils.renderPeriod\$3(t0, t4, null, 5));  // 10min 30s
console.log(TimeUtils.renderPeriod\$3(t0, t5, null, 5));  // 15h 10min 30s
console.log(TimeUtils.renderPeriod\$3(t0, t6, null, 5));  // 4d 15h 10min 30s
console.log(TimeUtils.renderPeriod\$3(t0, t7, null, 5));  // 10m 9d 15h 10min 30s
console.log(TimeUtils.renderPeriod\$3(t0, t8, null, 5));  // 16y
console.log(TimeUtils.renderPeriod\$3(t0, t9, null, 5));  // <current_date_and_time> - t0``````
🚀
Get your tech brand or product in front of software developers.
Posts you may like

Join