Live age display - javascript

I'm trying to display a live time elapsed on a page
So I have this function which calculates the exact time elapsed to the second, and when called, it updates the HTML node with this time. It seems woefully inefficient to use a setInterval to call this function every second to update the display. Can anyone suggest a better solution? Many thanks
$scope.getAge = function(){
var today = new Date();
var birthDate = new Date("1980-05-30T04:00:00");
var bdInMilis = birthDate.getTime();
var todayInMilis = today.getTime();
var timeAlive = todayInMilis - bdInMilis;
timeAlive = timeAlive/1000;
var numyears = Math.floor(timeAlive / 31536000);
var numdays = Math.floor((timeAlive % 31536000) / 86400);
var numhours = Math.floor(((timeAlive % 31536000) % 86400) / 3600);
var numminutes = Math.floor((((timeAlive % 31536000) % 86400) % 3600) / 60);
var numseconds = Math.floor((((timeAlive % 31536000) % 86400) % 3600) % 60);
var ageNode = document.getElementById("age-node");
if(ageNode){
ageNode.innerHTML = ("I am "+numyears+ " years, " + numdays + " days, " + numhours + " hours, " + numminutes + " minutes, " + numseconds + " seconds old (give or take)");
// can't keep doing this calculation every second
//$scope.refreshTime();
}
};

When you want a period of time using setInterval is better then timeouts (check this)
Also you're using angularjs, don't bind your string with innerHTML.
<div>{{age}}</div>
...
$scope.getAge = function(){
var today = new Date();
var birthDate = new Date("1980-05-30T04:00:00");
var bdInMilis = birthDate.getTime();
setInterval(function(){
var todayInMilis = today.getTime();
var timeAlive = todayInMilis - bdInMilis;
timeAlive = timeAlive/1000;
var numyears = Math.floor(timeAlive / 31536000);
var numdays = Math.floor((timeAlive % 31536000) / 86400);
var numhours = Math.floor(((timeAlive % 31536000) % 86400) / 3600);
var numminutes = Math.floor((((timeAlive % 31536000) % 86400) % 3600) / 60);
var numseconds = Math.floor((((timeAlive % 31536000) % 86400) % 3600) % 60);
$scope.age = "I am "+numyears+ " years, " + numdays + " days, " + numhours + " hours, " + numminutes + " minutes, " + numseconds + " seconds old (give or take)";
},1000);
};

Related

.getTime when $(document).ready for countdown

I want to make a countdown. Here's the algorithm :
var timeFinish, timeStart, timeNow, duration
timeStart <- the time when the document has ready
timeFinish <- timeStart + 1hour
timeNow <- get the time everytime (every second)
duration <- timeFinish - timeNow
output (duration)
I deliberately didn't write the algorithm for converting it into second etc (for shortening purpose, and I hope you get what I mean). Here's my code
$(document).ready(function() {
setInterval(countdown(), 1000);
function countdown() {
var hStart = new Date($(document).ready).getHours;
var mStart = new Date($(document).ready).getMinutes;
var sStart = new Date($(document).ready).getSeconds;
var secondTotalStart = (hStart * 3600) + (mStart * 60) + sStart;
var secondTotalFinish = secondTotalStart + 3600;
var hRunning = new Date().getHours;
var mRunning = new Date().getMinutes;
var sRunning = new Date().getSeconds;
var secondTotalRunning = (hRunning * 3600) + (mRunning * 60) + sRunning;
var duration = secondTotalFinish - secondTotalRunning;
var h = Math.floor(duration / 3600);
var m = Math.floor(duration % 3600) / 60;
var s = Math.floor(duration % 3600) % 60;
$("#countdown").html(h + " h : " + m + " m : " + s + " s");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="countdown"></div>
And my question is, how to get the timeStart? And is my code wrong?
I've corrected your code so you can look at mistakes:
$(document).ready(function() {
//below line: you must pass countdown as a function
setInterval(countdown, 1000);
var dt = new Date(); //get this out of countdown function
var hStart = dt.getHours();
var mStart = dt.getMinutes();
var sStart = dt.getSeconds();
var secondTotalStart = (hStart * 3600) + (mStart * 60) + sStart;
var secondTotalFinish = secondTotalStart + 3600;
function countdown() {
var cdt = new Date();
var hRunning = cdt.getHours();
var mRunning = cdt.getMinutes();
var sRunning = cdt.getSeconds();
var secondTotalRunning = (hRunning * 3600) + (mRunning * 60) + sRunning;
var duration = secondTotalFinish - secondTotalRunning;
var h = Math.floor(duration / 3600);
var m = Math.floor(duration % 3600 / 60);
var s = Math.floor(duration % 3600) % 60;
$("#countdown").html(h + " h : " + m + " m : " + s + " s");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="countdown"></div>
$(document).ready(function() {
var dTime = new Date(); //need to store the on-load time before set interval as a reference
setInterval(countdown, 1000);
function countdown() {
var hStart = dTime.getHours();//need to get the on-load hr, min and sec from the previously stored time.
var mStart = dTime.getMinutes();
var sStart = dTime.getSeconds();
var secondTotalStart = (hStart * 3600) + (mStart * 60) + sStart;
var secondTotalFinish = secondTotalStart + 3600;
var running = new Date()// store the current time into a variable
var hRunning = running.getHours();
var mRunning = running.getMinutes();
var sRunning = running.getSeconds();
var secondTotalRunning = (hRunning * 3600) + (mRunning * 60) + sRunning;
var duration = secondTotalFinish - secondTotalRunning;
var h = Math.floor(duration / 3600);
var m = Math.floor(duration % 3600) / 60;
var s = Math.floor(duration % 3600) % 60;
$("#countdown").html(h + " h : " + m + " m : " + s + " s");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="countdown"></div>
Did minor corrections. hope this helps
edit:
added some useful comments.

Javascript Convert Hours and Minutes into Days

I'm sorry if something similar might be discussed before, but I really need help with it.
Bellow is the code all I want to do is if the number goes over 24h it should switch to 1 day and 0 h, I can't figure it out if someone can please explain how to do it that would be so kind. I'm using it to calculate minutes and hours and want to have also days calculations if the number is higher then 24h.
Thanks in advance
//minutes to hour converter
function ConvertMinutes(num){
h = Math.floor(num/60);
m = num%60;
return(h + "hours"+" :"+" "+m+"minutes").toString();
}
var input = 68.68
console.log(ConvertMinutes(input));
You just need to divide the num by 1440, which is 24 hours in minutes...
Then you need a condition to display the "x days," when there is a value.
I also suggest you to round the minutes...
;)
//minutes to hour (and days) converter
function ConvertMinutes(num){
d = Math.floor(num/1440); // 60*24
h = Math.floor((num-(d*1440))/60);
m = Math.round(num%60);
if(d>0){
return(d + " days, " + h + " hours, "+m+" minutes");
}else{
return(h + " hours, "+m+" minutes");
}
}
var input1 = 68.68
console.log(ConvertMinutes(input1));
var input2 = 4568.68
console.log(ConvertMinutes(input2));
//minutes to hour converter
function ConvertMinutes(num){
h = Math.floor(num/60);
d = Math.floor(h/24);
h = h - d * 24
m = Math.floor(num%60)
s = ((input - d*24*60 - h*60 -m)*60).toFixed(2)
return('days: '+ d + ', hours: '+ h + ', minutes: ' +m+', seconds: '+s);
}
var input = 4568.68
console.log(ConvertMinutes(input));
By refactoring a bit your code, you could try something like the following:
function ConvertMinutes(num){
days = Math.floor(num/1440);
hours = Math.floor((num%1440)/60);
minutes = (num%1440)%60;
return {
days: days,
hours: hours,
minutes: minutes
};
}
var input = 68.68
console.log(ConvertMinutes(input));
function secondsToString(hours)
{
var seconds = hours * 60 * 60;
var numdays = Math.floor(seconds / 86400);
var numhours = Math.floor((seconds % 86400) / 3600);
var numminutes = Math.floor(((seconds % 86400) % 3600) / 60);
var numseconds = ((seconds % 86400) % 3600) % 60;
return numdays + " days " + numhours + " hours " + numminutes + " minutes " + numseconds + " seconds";
}

Javascript Countdown Timer Error

I am not able to know the reason, why my countdown timer is not working. Here is my code and jsfiddle link :http://jsfiddle.net/CHC8w/
<div id="idays"></div>
<div id="ihours"></div>
<div id="iminutes"></div>
<div id="iseconds"></div>
<script type="text/javascript">
jQuery(document).ready(function() {
setInterval(function(){
var future = new Date('Mar 28 2014 11:35:14');
var now = new Date('Mar 28 2014 11:05:14');
//var future = new Date("Sep 20 2014 21:15:00 GMT+0200");
//var now = new Date();
var difference = Math.floor((future - now) / 1000);
var seconds = fixIntegers(difference % 60);
difference = Math.floor(difference / 60);
var minutes = fixIntegers(difference % 60);
difference = Math.floor(difference / 60);
var hours = fixIntegers(difference % 24);
difference = Math.floor(difference / 24);
var days = difference;
jQuery("#iseconds").text(seconds + " sec");
jQuery("#iminutes").text(minutes + " min");
jQuery("#ihours").text(hours + " hr");
jQuery("#idays").text(days + " days");
}, 1000);
});
function fixIntegers(integer)
{
if (integer < 0)
integer = 0;
if (integer < 10)
return "0" + integer;
return "" + integer;
}
</script>
Kindly help.
Thanks
var now has fixed datetime value var now = new Date('Mar 28 2014 11:05:14'); during each call to setInterval()
Check this too http://jsfiddle.net/CHC8w/1/
// set the date we're counting down to
var target_date = new Date("Aug 15, 2019").getTime();
// variables for time units
var days, hours, minutes, seconds;
// get tag element
var countdown = document.getElementById("countdown");
// update the tag with id "countdown" every 1 second
setInterval(function () {
// find the amount of "seconds" between now and target
var current_date = new Date().getTime();
var seconds_left = (target_date - current_date) / 1000;
// do some time calculations
days = parseInt(seconds_left / 86400);
seconds_left = seconds_left % 86400;
hours = parseInt(seconds_left / 3600);
seconds_left = seconds_left % 3600;
minutes = parseInt(seconds_left / 60);
seconds = parseInt(seconds_left % 60);
// format countdown string + set tag value
countdown.innerHTML = days + "Days </br> " + hours + "hr</br>"
+ minutes + "min</br>" + seconds + "sec</br>";
}, 1000);
Source : https://mindgrader.com/tutorials/1-how-to-create-a-simple-javascript-countdown-timer.

Date return NAN in IE [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
IE JavaScript date parsing error
This code working fine in chrome and firefox but it didn't work in IE and safari. It return NAN in IE and invalid date in safair.
var date = new Date("2012-10-17T08:15:19.500-05:00");
var now = new Date();
var difference = now - date;
document.write( "Date: " + date.toLocaleString() + "<br/>");
document.write( "Now: " + now.toLocaleString() + "<br/>");
document.write( "Difference: " + differenceToString(difference) );
function differenceToString(milliseconds) {
var seconds = milliseconds / 1000;
var numyears = Math.floor(seconds / 31536000);
var numdays = Math.floor((seconds % 31536000) / 86400);
var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
var numseconds = Math.floor((((seconds % 31536000) % 86400) % 3600) % 60);
return numyears + " years, " + numdays + " days, " + numhours + " hours, " + numminutes + " minutes, " + numseconds + " seconds";
}
http://jsfiddle.net/RYS3R/
Any idea would be great help.
Thanks
You forgot the Z before the timezone offset, to get valid JS-parsed date according to the language specification - YYYY-MM-DDTHH:mm:ss.sssZ±hh:mm is the only format it must accept. Try
var date = new Date("2012-10-17T08:15:19.500Z-05:00");
…

Convert time interval given in seconds into more human readable form

I need a code snippet for converting amount of time given by number of seconds into some human readable form. The function should receive a number and output a string like this:
34 seconds
12 minutes
4 hours
5 days
4 months
1 year
No formatting required, hard-coded format will go.
function secondsToString(seconds)
{
var numyears = Math.floor(seconds / 31536000);
var numdays = Math.floor((seconds % 31536000) / 86400);
var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60;
return numyears + " years " + numdays + " days " + numhours + " hours " + numminutes + " minutes " + numseconds + " seconds";
}
With help of Royi we've got code that outputs time interval in a human readable form:
function millisecondsToStr (milliseconds) {
// TIP: to find current time in milliseconds, use:
// var current_time_milliseconds = new Date().getTime();
function numberEnding (number) {
return (number > 1) ? 's' : '';
}
var temp = Math.floor(milliseconds / 1000);
var years = Math.floor(temp / 31536000);
if (years) {
return years + ' year' + numberEnding(years);
}
//TODO: Months! Maybe weeks?
var days = Math.floor((temp %= 31536000) / 86400);
if (days) {
return days + ' day' + numberEnding(days);
}
var hours = Math.floor((temp %= 86400) / 3600);
if (hours) {
return hours + ' hour' + numberEnding(hours);
}
var minutes = Math.floor((temp %= 3600) / 60);
if (minutes) {
return minutes + ' minute' + numberEnding(minutes);
}
var seconds = temp % 60;
if (seconds) {
return seconds + ' second' + numberEnding(seconds);
}
return 'less than a second'; //'just now' //or other string you like;
}
If you are interested in an existing javascript library that does the job very well, you may want to check moment.js.
More specifically, the relevant moment.js piece for your question is durations.
Here are some examples of how you can take advantage of it to achieve your task:
var duration = moment.duration(31536000);
// Using the built-in humanize function:
console.log(duration.humanize()); // Output: "9 hours"
console.log(duration.humanize(true)); // Output: "in 9 hours"
moment.js has built-in support for 50+ human languages, so if you use the humanize() method you get multi-language support for free.
If you want to display the exact time information, you can take advantage of the moment-precise-range plug-in for moment.js that was created exactly for this purpose:
console.log(moment.preciseDiff(0, 39240754000);
// Output: 1 year 2 months 30 days 5 hours 12 minutes 34 seconds
One thing to note is that currently moment.js does not support weeks / days (in week) for duration object.
Hope this helps!
Took a swing based on #Royi's response:
/**
* Translates seconds into human readable format of seconds, minutes, hours, days, and years
*
* #param {number} seconds The number of seconds to be processed
* #return {string} The phrase describing the amount of time
*/
function forHumans ( seconds ) {
var levels = [
[Math.floor(seconds / 31536000), 'years'],
[Math.floor((seconds % 31536000) / 86400), 'days'],
[Math.floor(((seconds % 31536000) % 86400) / 3600), 'hours'],
[Math.floor((((seconds % 31536000) % 86400) % 3600) / 60), 'minutes'],
[(((seconds % 31536000) % 86400) % 3600) % 60, 'seconds'],
];
var returntext = '';
for (var i = 0, max = levels.length; i < max; i++) {
if ( levels[i][0] === 0 ) continue;
returntext += ' ' + levels[i][0] + ' ' + (levels[i][0] === 1 ? levels[i][1].substr(0, levels[i][1].length-1): levels[i][1]);
};
return returntext.trim();
}
Nice thing about mine is that there is no repetitive ifs, and won't give you 0 years 0 days 30 minutes 1 second for example.
For example:
forHumans(60) outputs 1 minute
forHumans(3600) outputs 1 hour
and forHumans(13559879) outputs 156 days 22 hours 37 minutes 59 seconds
Try following:
seconds = ~~(milliseconds / 1000);
minutes = ~~(seconds / 60);
hours = ~~(minutes / 60);
days = ~~(hours / 24);
weeks = ~~(days / 7);
year = ~~(days / 365);
Note:
A usual year has 365 days. A leap year has 366 days, so you need additional check if this is an issue for you.
The similar problem with daylight saving. Some days have 23 and some 25 hours when time's changed.
Conclusion: this is a rude but small and simple snippet :)
millisToTime = function(ms){
x = ms / 1000;
seconds = Math.round(x % 60);
x /= 60;
minutes = Math.round(x % 60);
x /= 60;
hours = Math.round(x % 24);
x /= 24;
days = Math.round(x);
return {"Days" : days, "Hours" : hours, "Minutes" : minutes, "Seconds" : seconds};
}
This will take milliseconds as an int, and give you an JSON object containing all the info you could need
Way more simple and readable.
milliseconds = 12345678;
mydate=new Date(milliseconds);
humandate=mydate.getUTCHours()+" hours, "+mydate.getUTCMinutes()+" minutes and "+mydate.getUTCSeconds()+" second(s)";
Which gives:
"3 hours, 25 minutes and 45 second(s)"
To Convert time in millisecond to human readable format.
function timeConversion(millisec) {
var seconds = (millisec / 1000).toFixed(1);
var minutes = (millisec / (1000 * 60)).toFixed(1);
var hours = (millisec / (1000 * 60 * 60)).toFixed(1);
var days = (millisec / (1000 * 60 * 60 * 24)).toFixed(1);
if (seconds < 60) {
return seconds + " Sec";
} else if (minutes < 60) {
return minutes + " Min";
} else if (hours < 24) {
return hours + " Hrs";
} else {
return days + " Days"
}
}
Thanks to #Dan / # Royi for the logic. However the implementation doesn't build time string like XX days, XX mins. I adjusted their code a bit:
function millisecondsToStr( milliseconds ) {
let temp = milliseconds / 1000;
const years = Math.floor( temp / 31536000 ),
days = Math.floor( ( temp %= 31536000 ) / 86400 ),
hours = Math.floor( ( temp %= 86400 ) / 3600 ),
minutes = Math.floor( ( temp %= 3600 ) / 60 ),
seconds = temp % 60;
if ( days || hours || seconds || minutes ) {
return ( years ? years + "y " : "" ) +
( days ? days + "d " : "" ) +
( hours ? hours + "h " : "" ) +
( minutes ? minutes + "m " : "" ) +
Number.parseFloat( seconds ).toFixed( 2 ) + "s";
}
return "< 1s";
}
When one runs it
console.log("=", millisecondsToStr( 1540545689739 - 1540545684368 ));
console.log("=", millisecondsToStr( 351338536000 ));
The results look like:
= 5.37s
= 11y 51d 10h 2m 16.00s
Adding to the myriad of methods, here's a cheap and short way to retrieve a human readable time with only a single time unit.
const timeScalars = [1000, 60, 60, 24, 7, 52];
const timeUnits = ['ms', 'secs', 'mins', 'hrs', 'days', 'weeks', 'years'];
const getHumanReadableTime = (ms, dp = 0) => {
let timeScalarIndex = 0, scaledTime = ms;
while (scaledTime > timeScalars[timeScalarIndex]) {
scaledTime /= timeScalars[timeScalarIndex++];
}
return `${scaledTime.toFixed(dp)} ${timeUnits[timeScalarIndex]}`;
};
Example outputs:
getHumanReadableTime(512000);
getHumanReadableTime(5120000);
getHumanReadableTime(51200000);
getHumanReadableTime(51200000, 2);
getHumanReadableTime(51200000, 6);
/*
Output:
'9 min'
'1 hrs'
'14 hrs'
'14.22 hrs'
'14.222222 hrs'
*/
function millisecondsToString(milliseconds) {
var oneHour = 3600000;
var oneMinute = 60000;
var oneSecond = 1000;
var seconds = 0;
var minutes = 0;
var hours = 0;
var result;
if (milliseconds >= oneHour) {
hours = Math.floor(milliseconds / oneHour);
}
milliseconds = hours > 0 ? (milliseconds - hours * oneHour) : milliseconds;
if (milliseconds >= oneMinute) {
minutes = Math.floor(milliseconds / oneMinute);
}
milliseconds = minutes > 0 ? (milliseconds - minutes * oneMinute) : milliseconds;
if (milliseconds >= oneSecond) {
seconds = Math.floor(milliseconds / oneSecond);
}
milliseconds = seconds > 0 ? (milliseconds - seconds * oneSecond) : milliseconds;
if (hours > 0) {
result = (hours > 9 ? hours : "0" + hours) + ":";
} else {
result = "00:";
}
if (minutes > 0) {
result += (minutes > 9 ? minutes : "0" + minutes) + ":";
} else {
result += "00:";
}
if (seconds > 0) {
result += (seconds > 9 ? seconds : "0" + seconds) + ":";
} else {
result += "00:";
}
if (milliseconds > 0) {
result += (milliseconds > 9 ? milliseconds : "0" + milliseconds);
} else {
result += "00";
}
return result;
}
Here is my take.
Feel free to play around with it in the jsbin.
// This returns a string representation for a time interval given in milliseconds
// that appeals to human intuition and so does not care for leap-years,
// month length irregularities and other pesky nuisances.
const human_millis = function (ms, digits=1) {
const levels=[
["ms", 1000],
["sec", 60],
["min", 60],
["hrs", 24],
["days", 7],
["weeks", (30/7)], // Months are intuitively around 30 days
["months", 12.1666666666666666], // Compensate for bakari-da in last step
["years", 10],
["decades", 10],
["centuries", 10],
["millenia", 10],
];
var value=ms;
var name="";
var step=1;
for(var i=0, max=levels.length;i<max;++i){
value/=step;
name=levels[i][0];
step=levels[i][1];
if(value < step){
break;
}
}
return value.toFixed(digits)+" "+name;
}
console.clear();
console.log("---------");
console.log(human_millis(1));
console.log(human_millis(10));
console.log(human_millis(100));
console.log(human_millis(1000));
console.log(human_millis(1000*60));
console.log(human_millis(1000*60*60));
console.log(human_millis(1000*60*60*24));
console.log(human_millis(1000*60*60*24*7));
console.log(human_millis(1000*60*60*24*30));
console.log(human_millis(1000*60*60*24*365));
console.log(human_millis(1000*60*60*24*365*10));
console.log(human_millis(1000*60*60*24*365*10*10));
console.log(human_millis(1000*60*60*24*365*10*10*10));
console.log(human_millis(1000*60*60*24*365*10*10*10*10));
If you use Typescript type and cast to make it work
let name : string | number = "";
let step : string | number =1;
for(var i=0, max=levels.length;i<max;++i){
value/= step as number;
name=levels[i][0];
step=levels[i][1];
if(value < step){
break;
}
}
Output:
"---------"
"1.0 ms"
"10.0 ms"
"100.0 ms"
"1.0 sec"
"1.0 min"
"1.0 hrs"
"1.0 days"
"1.0 weeks"
"1.0 months"
"1.0 years"
"1.0 decades"
"1.0 centuries"
"1.0 millenia"
"10.0 millenia"
This function outputs seconds in this format : 11h 22m, 1y 244d, 42m 4s etc
Set the max variable to show as many identifiers as you want.
function secondsToString (seconds) {
var years = Math.floor(seconds / 31536000);
var max =2;
var current = 0;
var str = "";
if (years && current<max) {
str+= years + 'y ';
current++;
}
var days = Math.floor((seconds %= 31536000) / 86400);
if (days && current<max) {
str+= days + 'd ';
current++;
}
var hours = Math.floor((seconds %= 86400) / 3600);
if (hours && current<max) {
str+= hours + 'h ';
current++;
}
var minutes = Math.floor((seconds %= 3600) / 60);
if (minutes && current<max) {
str+= minutes + 'm ';
current++;
}
var seconds = seconds % 60;
if (seconds && current<max) {
str+= seconds + 's ';
current++;
}
return str;
}
With the help of Dan answer, I came up with this if you want to calculate the difference between the post created time (from DB it should be retrieved as UTC) and the users system time and then show them the elapsed time, you could use below function
function dateToStr(input_date) {
input_date= input_date+" UTC";
// convert times in milliseconds
var input_time_in_ms = new Date(input_date).getTime();
var current_time_in_ms = new Date().getTime();
var elapsed_time = current_time_in_ms - input_time_in_ms;
function numberEnding (number) {
return (number > 1) ? 's' : '';
}
var temp = Math.floor(elapsed_time / 1000);
var years = Math.floor(temp / 31536000);
if (years) {
return years + ' year' + numberEnding(years);
}
//TODO: Months! Maybe weeks?
var days = Math.floor((temp %= 31536000) / 86400);
if (days) {
return days + ' day' + numberEnding(days);
}
var hours = Math.floor((temp %= 86400) / 3600);
if (hours) {
return hours + ' hour' + numberEnding(hours);
}
var minutes = Math.floor((temp %= 3600) / 60);
if (minutes) {
return minutes + ' minute' + numberEnding(minutes);
}
var seconds = temp % 60;
if (seconds) {
return seconds + ' second' + numberEnding(seconds);
}
return 'less than a second'; //'just now' //or other string you like;
}
eg: usage
var str = dateToStr('2014-10-05 15:22:16');
There is the Intl.RelativeTimeFormat API, which is supported in recent versions of Chrome and Firefox.
An few examples:
let rtf = new Intl.RelativeTimeFormat("en");
rtf.format(-1, "day"); // 'yesterday'
rtf.format(-2, 'day'); // '2 days ago'
rtf.format(13.37, 'second'); // 'in 13.37 seconds'
And there's a lot more in this blog post and in the proposal itself.
To show only what you need and not day 0, hours 0...
formatTime = function(time) {
var ret = time % 1000 + ' ms';
time = Math.floor(time / 1000);
if (time !== 0) {
ret = time % 60 + "s "+ret;
time = Math.floor(time / 60);
if (time !== 0) {
ret = time % 60 + "min "+ret;
time = Math.floor(time / 60);
if (time !== 0) {
ret = time % 60 + "h "+ret;
...
}
}
}
return ret;
};
Following a similar approach to #Dan, I have modified #Royi Namir's code to output a string with commas and and's:
secondsToString = function(seconds) {
var numdays, numhours, nummilli, numminutes, numseconds, numyears, res;
numyears = Math.floor(seconds / 31536000);
numdays = Math.floor(seconds % 31536000 / 86400);
numhours = Math.floor(seconds % 31536000 % 86400 / 3600);
numminutes = Math.floor(seconds % 31536000 % 86400 % 3600 / 60);
numseconds = seconds % 31536000 % 86400 % 3600 % 60;
nummilli = seconds % 1.0;
res = [];
if (numyears > 0) {
res.push(numyears + " years");
}
if (numdays > 0) {
res.push(numdays + " days");
}
if (numhours > 0) {
res.push(numhours + " hours");
}
if (numminutes > 0) {
res.push(numminutes + " minutes");
}
if (numseconds > 0) {
res.push(numseconds + " seconds");
}
if (nummilli > 0) {
res.push(nummilli + " milliseconds");
}
return [res.slice(0, -1).join(", "), res.slice(-1)[0]].join(res.length > 1 ? " and " : "");
};
It has no period so one can add sentences after it, like here:
perform: function(msg, custom, conn) {
var remTimeLoop;
remTimeLoop = function(time) {
if (time !== +custom[0]) {
msg.reply((secondsToString(time)) + " remaining!");
}
if (time > 15) {
return setTimeout((function() {
return remTimeLoop(time / 2);
}), time / 2);
}
};
// ...
remTimeLoop(+custom[0]);
}
Where custom[0] is the total time to wait for; it will keep dividing the time by 2, warning the time remaining until the timer ends, and stop warning once the time is under 15 seconds.
Below will work for both past and future datetime, also have option to pass locale.
function relativeTime(isoString, locale = "en") {
const timestamp = Date.parse(isoString);
const msPerMinute = 60 * 1000;
const msPerHour = msPerMinute * 60;
const msPerDay = msPerHour * 24;
const msPerMonth = msPerDay * 30;
const msPerYear = msPerDay * 365;
const current = Date.now();
let elapsed = current - timestamp;
const sign = elapsed > 0 ? -1 : 1;
elapsed = Math.abs(elapsed);
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
if (elapsed < msPerMinute) {
return rtf.format(sign * Math.floor(elapsed / 1000), "seconds");
} else if (elapsed < msPerHour) {
return rtf.format(sign * Math.floor(elapsed / msPerMinute), "minutes");
} else if (elapsed < msPerDay) {
return rtf.format(sign * Math.floor(elapsed / msPerHour), "hours");
} else if (elapsed < msPerMonth) {
return rtf.format(sign * Math.floor(elapsed / msPerDay), "days");
} else if (elapsed < msPerYear) {
return rtf.format(sign * Math.floor(elapsed / msPerMonth), "months");
} else {
return new Date(timestamp).toLocaleString(locale);
}
}
Output:
relativeTime(new Date().toISOString()) //'2021-11-13T18:48:58.243Z'
-> now
relativeTime('2021-11-13T18:48:50.243Z')
-> 8 seconds ago
relativeTime('2021-11-14T18:48:50.243Z')
-> in 23 hours
relativeTime('2021-11-15T18:48:50.243Z')
-> tomorrow
relativeTime('2021-10-15T18:48:50.243Z')
-> 29 days ago
relativeTime('2021-12-15T18:48:50.243Z')
-> next month
This is a solution. Later you can split by ":" and take the values of the array
/**
* Converts milliseconds to human readeable language separated by ":"
* Example: 190980000 --> 2:05:3 --> 2days 5hours 3min
*/
function dhm(t){
var cd = 24 * 60 * 60 * 1000,
ch = 60 * 60 * 1000,
d = Math.floor(t / cd),
h = '0' + Math.floor( (t - d * cd) / ch),
m = '0' + Math.round( (t - d * cd - h * ch) / 60000);
return [d, h.substr(-2), m.substr(-2)].join(':');
}
//Example
var delay = 190980000;
var fullTime = dhm(delay);
console.log(fullTime);
I'm a big fan of objects, so I created this from https://metacpan.org/pod/Time::Seconds
Usage:
var human_readable = new TimeSeconds(986543).pretty(); // 11 days, 10 hours, 2 minutes, 23 seconds
;(function(w) {
var interval = {
second: 1,
minute: 60,
hour: 3600,
day: 86400,
week: 604800,
month: 2629744, // year / 12
year: 31556930 // 365.24225 days
};
var TimeSeconds = function(seconds) { this.val = seconds; };
TimeSeconds.prototype.seconds = function() { return parseInt(this.val); };
TimeSeconds.prototype.minutes = function() { return parseInt(this.val / interval.minute); };
TimeSeconds.prototype.hours = function() { return parseInt(this.val / interval.hour); };
TimeSeconds.prototype.days = function() { return parseInt(this.val / interval.day); };
TimeSeconds.prototype.weeks = function() { return parseInt(this.val / interval.week); };
TimeSeconds.prototype.months = function() { return parseInt(this.val / interval.month); };
TimeSeconds.prototype.years = function() { return parseInt(this.val / interval.year); };
TimeSeconds.prototype.pretty = function(chunks) {
var val = this.val;
var str = [];
if(!chunks) chunks = ['day', 'hour', 'minute', 'second'];
while(chunks.length) {
var i = chunks.shift();
var x = parseInt(val / interval[i]);
if(!x && chunks.length) continue;
val -= interval[i] * x;
str.push(x + ' ' + (x == 1 ? i : i + 's'));
}
return str.join(', ').replace(/^-/, 'minus ');
};
w.TimeSeconds = TimeSeconds;
})(window);
I cleaned up one of the other answers a bit provides nice '10 seconds ago' style strings:
function msago (ms) {
function suffix (number) { return ((number > 1) ? 's' : '') + ' ago'; }
var temp = ms / 1000;
var years = Math.floor(temp / 31536000);
if (years) return years + ' year' + suffix(years);
var days = Math.floor((temp %= 31536000) / 86400);
if (days) return days + ' day' + suffix(days);
var hours = Math.floor((temp %= 86400) / 3600);
if (hours) return hours + ' hour' + suffix(hours);
var minutes = Math.floor((temp %= 3600) / 60);
if (minutes) return minutes + ' minute' + suffix(minutes);
var seconds = Math.floor(temp % 60);
if (seconds) return seconds + ' second' + suffix(seconds);
return 'less then a second ago';
};
function java_seconds_to_readable(seconds)
{
var numhours = Math.floor(seconds / 3600);
var numminutes = Math.floor((seconds / 60) % 60);
var numseconds = seconds % 60;
return numhours + ":" + numminutes + ":" + numseconds;
}
More simple way. You can years and days respectively.
if you use node :
const humanize = require('human-date');
let yesterday = new Date(new Date().setDate(new Date().getDate()-1));
console.log(humanize.relativeTime(yesterday)); //=> 1 day ago
function secondsToTimeString(input) {
let years = 0, days = 0, hours = 0, minutes = 0, seconds = 0;
let ref = [31536000,86400,3600,60,1];
for (let i = 0;i < ref.length;i++) {
let val = ref[i];
while (val <= input) {
input -= val;
if (i === 0) years++;
if (i === 1) days++;
if (i === 2) hours++;
if (i === 3) minutes++;
if (i === 4) seconds++;
}
return {years, days, hours, minutes, seconds};
}

Categories