Some time ago, I’ve wrote an article ^{iCompile – PHP Human-Readable Time Diff (“5 Hours Ago”, “Will Be In A Day”,…)},

running the “main action” procedure in a recursive-loop, I could improve the spectrum of the result, so it will include also complex time-periods (“5 hours, 100 milliseconds”, “3 years, 12 days”, “3 days, 14 seconds”, etc…)

among other code improvements :)

_{[also available in my github’s gist: https://gist.github.com/eladkarako/65b3b395c5c9d5233f104eceeb7cede4]}

function human_time_diff(from, to){ /*accept unix-datetime integer, Date object or date string, fallback is current date*/ "use strict"; var now, diff; /*---*/ function difference(diff){ var MINUTE_IN_SECONDS = 60 , HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS , DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS , MONTH_IN_SECONDS = 30 * DAY_IN_SECONDS , YEAR_IN_SECONDS = 365 * DAY_IN_SECONDS , since , milliseconds, seconds, minutes, hours, days, months, years ; if(0 === diff){ since = "0 seconds"; } else if(diff > 0 && diff < 1){ milliseconds = Math.trunc(diff * 1000); since = milliseconds + " " + (1 === milliseconds ? "millisecond" : "milliseconds"); } else if(diff >= 1 && diff < MINUTE_IN_SECONDS){ seconds = Math.trunc(diff); seconds = Math.max(diff, 1); since = seconds + " " + (1 === seconds ? "second" : "seconds"); diff = diff - (seconds); if(diff > 0) since = since + ", " + difference(diff); /* calculate leftover time, recursively */ } else if(diff >= MINUTE_IN_SECONDS && diff < HOUR_IN_SECONDS){ minutes = Math.trunc(diff / MINUTE_IN_SECONDS); minutes = Math.max(minutes, 1); since = minutes + " " + (1 === minutes ? "minute" : "minutes"); diff = diff - (minutes * MINUTE_IN_SECONDS); if(diff > 0) since = since + ", " + difference(diff); /* calculate leftover time, recursively */ } else if(diff >= HOUR_IN_SECONDS && diff < DAY_IN_SECONDS){ hours = Math.trunc(diff / HOUR_IN_SECONDS); hours = Math.max(hours, 1); since = hours + " " + (1 === hours ? "hour" : "hours"); diff = diff - (hours * HOUR_IN_SECONDS); if(diff > 0) since = since + ", " + difference(diff); /* calculate leftover time, recursively */ } else if(diff >= DAY_IN_SECONDS && diff < MONTH_IN_SECONDS){ days = Math.trunc(diff / DAY_IN_SECONDS); days = Math.max(days, 1); since = days + " " + (1 === days ? "day" : "days"); diff = diff - (days * DAY_IN_SECONDS); if(diff > 0) since = since + ", " + difference(diff); /* calculate leftover time, recursively */ } else if(diff >= MONTH_IN_SECONDS && diff < YEAR_IN_SECONDS){ months = Math.trunc(diff / MONTH_IN_SECONDS); months = Math.max(months, 1); since = months + " " + (1 === months ? "month" : "months"); diff = diff - (months * MONTH_IN_SECONDS); if(diff > 0) since = since + ", " + difference(diff); /* calculate leftover time, recursively */ } else if (diff >= YEAR_IN_SECONDS){ years = Math.trunc(diff / YEAR_IN_SECONDS); years = Math.max(diff, 1); since = years + " " + (1 === years ? "year" : "years"); diff = diff - (years * YEAR_IN_SECONDS); if(diff > 0) since = since + ", " + difference(diff); /* calculate leftover time, recursively */ } return since; } /*---*/ now = new Date(); from = ("number" === typeof from) ? Math.max(from, 0) : ("string" === typeof from) ? Number(new Date(from)) : ("object" === typeof from && "date" === from.constructor.name.toLowerCase()) ? Number(from) : Number(now) ; to = ("number" === typeof to) ? Math.max(to, 0) : ("string" === typeof to) ? Number(new Date(to)) : ("object" === typeof to && "date" === to.constructor.name.toLowerCase()) ? Number(to) : Number(now) if("nan" === String(from).toLowerCase()) throw new Error("Error While Converting Date (first argument)" ); if("nan" === String(to).toLowerCase()) throw new Error("Error While Converting Date (second argument)"); diff = Math.abs(from - to); console.log(from,to,diff); return difference(diff); } /* human_time_diff(); // 0 seconds human_time_diff("22:15:40"); // ERROR (invalid date format) human_time_diff( Number(new Date()) - 2000 ); // 33 minutes, 20 seconds human_time_diff( Number(new Date()) - 300 ); // 5 minutes human_time_diff( Number(new Date()) - 300.123 ); // 5 minutes, 123 milliseconds */