Languages
[Edit]
EN

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

5 points
Created by:
Gigadude
791

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

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

 

Custom time period example

In this section, dates are converted to milliseconds difference. Based on the difference we are able in a simple way to calculate the 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 = '';
  	function addPart(value, unit) {
      	if (value) {
            if (result) {
                result += ' ';
            }
            result += value + ' ' + (value === 1 ? unit : unit + 's');
        }
    }
  	addPart(period.days, 'day');
    addPart(period.hours, 'hour');
    addPart(period.minutes, 'minute');
    addPart(period.seconds, 'second');
  	addPart(period.milliseconds, 'millisecond');
  	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

 

Alternative implementation example

This approach allows to:

  • render string with the indicated amount of parts (e.g. 2 parts 10s 30min),
  • use custom units (labels array as the last argument),
  • select a message to display when the precision of labels is not enough (e.g. done variable can be set as 'Now' when we want to say the 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

 

Alternative titles

  1. JavaScript - calculate time span (timespan)
  2. JavaScript - calculate time moment
  3. JavaScript - how to calculate time period (time difference in days, minutes, seconds and milliseconds)?
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join