Simple datetime diff

by IceCreamYou

JavaScript

function log(s) {
	var x = document.createElement('div');
  x.textContent = s;
  document.body.appendChild(x);
}

var tiers = [
  {
    max: 1000 * 60,
    postfix: {
      short: 's',
    },
  },
  {
    max: 1000 * 60 * 60,
    postfix: {
      short: 'm',
    },
  },
  {
    max: 1000 * 60 * 60 * 24,
    postfix: {
      short: 'h',
    },
  },
  {
    max: 1000 * 60 * 60 * 24 * 365,
    postfix: {
      short: 'd',
    },
  },
  {
    max: Infinity,
    postfix: {
      short: 'y',
    },
  },
];

/**
 * Returns the distance between two dates.
 *
 * This isn't super accurate - in particular it ignores time changes like DST
 * and leap time - but it is "good enough" for casual short-term use. The "real"
 * solution is to use a library like http://timeago.org/
 *
 * This implementation supports minute, hour, day, and year breakdowns.
 * Values less than a minute are represented as "<1m." Ex.:
 *
 * ```js
 * getTimeDiffInWords(new Date('2011-02-14T04:44:01.532Z'), new Date('2017-07-18T06:46:02.532Z'), 'short', 2)
 * // Returns "6y 156d"
 * ```
 *
 * @param d1 The first date (order doesn't matter).
 * @param d2 The second date (order doesn't matter).
 * @param format The duration format (e.g. "short" to output "3h").
 * @param granularity The number of parts to return (e.g. 2 to output "3h 2m").
 */
function getTimeDiffInWords(d1, d2, format, granularity) {
	return _getTimeDiffInWords(Math.abs(d1.getTime() - d2.getTime()), format, granularity);
}

function _getTimeDiffInWords(diff, format, granularity) {
  if (diff < tiers[0].max && format === 'short') {
  	return '<1m';
  }
  for (var i = 1; i < tiers.length; i++) {
    if (diff < tiers[i].max) {
      return Math[granularity > 1 ? 'floor' : 'round'](diff / tiers[i-1].max) + tiers[i].postfix[format] +
      	(i > 1 && --granularity ?
        	' ' + _getTimeDiffInWords(diff - Math.floor(diff / tiers[i-1].max) * tiers[i-1].max, format, granularity) :
          ''
        );
    }
  }
}

// For illustration
var d =...