Converting milliseconds while detecting single digit integers - javascript

I created a function that detects and converts milliseconds to minutes and seconds. What I'd like to do is prepend a zero on either (or both) the minute and second variables if the number comes out to be less than ten. So for instance if I had an integer 184213 which evaluates to 3:4 I'd like it to be 03:04. Is there a short and concise way to do this without having to write out a long conditional or ternary?
msToTime(184213);
function msToTime(milliseconds) {
var minutes = parseInt(milliseconds/(1000*60)%60),
seconds = parseInt((milliseconds/1000)%60);
return minutes + ':' + seconds;
}

A slightly different approach utilizing Date and slice:
function msToTime(milliseconds) {
var date = new Date(milliseconds);
return date.toTimeString().slice(3,8);
}
msToTime(184213);
// outputs: "03:04"
A small caveat is this will of course have a limit of "23:59" and will always be the floor value as any milliseconds value over the minutes will not be shown.

Try this:
msToTime(184213);
function msToTime(milliseconds) {
var minutes = parseInt(milliseconds/(1000*60)%60),
seconds = parseInt((milliseconds/1000)%60);
return ('0' + minutes).slice(-2) + ':' + ('0' + seconds).slice(-2);
}

Related

Formatting time difference as `mm:ss` with date fns

I'm currently using https://date-fns.org/v2.21.1/docs/differenceInSeconds to format distance between 2 dates in seconds, but if such distance is greater than 1min, various results come up like 67 seconds.
To make it more user friendly, I'd like to format this distance as mm:ss so
00:59
01:00
02:34
And so on. Currently closest I got to is using differenceInSeconds and differenceInMinutes and just concatenating 2 into a string like ${differenceInMinutes}:${differenceInSeconds} issue is, that for 2 minutes I get result like 02:120
You need to use the modulo (%) operator, it returns the remainder of division.
I've also used the padStart function to have the leading zeros displayed in the final string.
As the argument you just need to use the difference in seconds,
Here's a code snippet:
function formatTime(time) {
// Remainder of division by 60
var seconds = time % 60;
// Divide by 60 and floor the result (get the nearest lower integer)
var minutes = Math.floor(time / 60);
// Put it all in one string
return ("" + minutes).padStart(2, "0") + ":" + ("" + seconds).padStart(2, "0");
}
console.log(formatTime(15))
console.log(formatTime(65))
console.log(formatTime(123))

Why does my digital clock function leak memory?

I have a digital clock function that takes the hours, minutes, and seconds from a JSON result, parses them as integers, does math on them (add 1 to the seconds every time it's looped through, if the seconds is 0, add 1 to minutes, etc.). After that math I parse these three variables as strings so I can then pad them with leading 0's for a result that looks like
10:05:34
(hours, minutes, seconds).
I use this method rather than datetimes because JS will always parse datetimes in local time, but the three variables are based on server time.
function countTime(){
timeSeconds = parseInt(timeSeconds);
timeMinutes = parseInt(timeMinutes);
timeHours = parseInt(timeHours);
timeSeconds = (timeSeconds + 1);
if (timeSeconds == 60){timeMinutes = (timeMinutes + 1); timeSeconds = 0;};
if (timeMinutes == 60){timeHours = (timeHours + 1); timeMinutes = 0;};
//convert from 24 to 12 hour time, and "0" hour to 12
if (timeHours > 12){
timeHours = (timeHours - 12)
};
if (timeHours == 0){
timeHours = 12;
};
//back to strings so that 0s can be padded
timeSeconds = timeSeconds.toString();
timeMinutes = timeMinutes.toString();
timeHours = timeHours.toString();
//pad 0s
if (timeSeconds <= 10 && timeSeconds.length < 2)(timeSeconds = ("0" + timeSeconds));
if (timeMinutes <= 10 && timeMinutes.length < 2)(timeMinutes = ("0" + timeMinutes));
if (timeHours <= 10 && timeHours.length < 2)(timeHours = ("0" + timeHours));
//show time
timetext = timeHours + ":" + timeMinutes + ":" + timeSeconds
$('#BT').html(timetext);
};
Which is called by this function that sets it at an interval:
function updateTime() {
countTime();
timeInt = setInterval(countTime,1000);
console.log('updated time from server');
};
timeInt is initialized globally before so I can clear that interval on a window focus event.
When I take this function out of my page, I have a memory use of around ~20kb that stays fairly certain. With this function included, memory use starts around 40kb and increases every second (which I think indicates a memory leak. . .). updateTime is called on a nonstandard interval (around every 45 minutes by the success callback of the AJAX call that gets timeHours,timeMinutes, and timeSeconds. Do I have a scope problem? Am I redifining variables needlessly when I have countTime on an interval?
You are leaking the interval timers. You need to call clearInterval before initializing it again.
function updateTime() {
countTime();
clearInterval(timeInt); // Here
timeInt = setInterval(countTime,1000);
console.log('updated time from server');
};

Is there a simple way to convert a decimal time (e.g. 1.074 minutes) into mm:ss format using moment.js?

I was wondering if there's a simple way, using moment.js library, to transform a decimal time interval (for example, 1.074 minutes) into its equivalent 'mm:ss' value. I am currently using a function which doesn't work too well with negative times (it outputs the value in '-m:ss' format):
function secTommss(sec){
var min = Math.floor(sec/60)
sec = Math.round(Math.abs(sec) % 60);
return min + ":" + (sec < 10 ? "0" + sec : sec)
}
Here is some JavaScript that will do what you are asking:
function minTommss(minutes){
var sign = minutes < 0 ? "-" : "";
var min = Math.floor(Math.abs(minutes));
var sec = Math.floor((Math.abs(minutes) * 60) % 60);
return sign + (min < 10 ? "0" : "") + min + ":" + (sec < 10 ? "0" : "") + sec;
}
Examples:
minTommss(3.5) // "03:30"
minTommss(-3.5) // "-03:30"
minTommss(36.125) // "36:07"
minTommss(-9999.999) // "-9999:59"
You could use moment.js durations, such as
moment.duration(1.234, 'minutes')
But currently, there's no clean way to format a duration in mm:ss like you asked, so you'd be re-doing most of that work anyway.
Using moment:
function formatMinutes(mins){
return moment().startOf('day').add(mins, 'minutes').format('m:ss');
}
using just js, here's a really simple and fast way to do this for up to 12 hours:
function secTommss2(sec){
return new Date(sec*1000).toUTCString().split(" ")[4]
}
maybe I am a bit late to the party, but still... my two cents:
you can build the variable in seconds, parse it as a date, and then cut it to a string or whatever format you want to use it:
let totalTimeInSeconds = 1.074 * 60;
let result = new Date(null, null, null, null, null, totalTimeInSeconds);
console.log(result.toTimeString().split(' ').[0].substring(3));
and the output will be:
01:14

Count-Up Timer on each page load from 0

I want to implement a count-up timer JS code that starts counting at each load page from 0. The code which I've now is like this:
var secondsTotal = 0;
setInterval(function() {
++secondsTotal;
var minutes = Math.floor(secondsTotal / 60);
var seconds = Math.floor(secondsTotal) % 60;
var milliseconds = Math.floor(secondsTotal) % 1000;
document.getElementById('counter').innerHTML = minutes + ":" + seconds + "." + milliseconds;
}, 1000);
The output format should be: 00:00.0
mm:ss.ms
So, how to output the result like above format (minutes and seconds should be exactly printed in two digits format)?
If you want to do it per-page, you're almost there. Right now, your code does not allow you to track milliseconds, as your setInterval runs every second. What I would recommend instead is something like this:
(function() {
var counter = 0,
cDisplay = document.getElementById("counter");
format = function(t) {
var minutes = Math.floor(t/600),
seconds = Math.floor( (t/10) % 60);
minutes = (minutes < 10) ? "0" + minutes.toString() : minutes.toString();
seconds = (seconds < 10) ? "0" + seconds.toString() : seconds.toString();
cDisplay.innerHTML = minutes + ":" + seconds + "." + Math.floor(t % 10);
};
setInterval(function() {
counter++;
format(counter);
},100);
})();
This does a couple of things to allow your code to run 10 times per second:
The output element, #counter, is cached and not retrieved every iteration
The formatting is kept to arithmetic operations only - modulo and division.
This now also adds leading zeroes.
If you would like to keep this counter running page-per-page, consider using document.cookies to pass the final value from page to page.
Fiddle
This serves as a good first version. However, you may want to:
Pause/re-start your timer
Reset your timer
Have multiple timers
For this reason, I will add a slightly more complex form of the above code, which will allow you to manage multiple timers. This will make use of a few OO concepts. We will use a TimerManager object to "host" our timers, and each Timer object will have a link to the manager.
The reason for this is because every timer will depend on the same setInterval() by doing it this way, rather than to have multiple setInterval() calls. This allows you to cut down on wasted clock cycles.
More on this in about 5 minutes!
Counting seconds that way isn't guaranteed to be accurate. The setInterval method can drift on you based upon the JS engine's ability to complete its other tasks. Not sure what your use case is, such as how long you expect to count up, but it's worth taking note of. See Will setInterval drift? for a detailed explanation.
I'd recommend you check out the momentjs plugin # http://momentjs.com/ and update your code to something like the following
var startTime = moment();
var el = document.getElementById('counter');
setInterval(function() {
var ms = moment().diff(startTime),
min = moment.duration(ms).minutes(),
sec = moment.duration(ms).seconds();
ms = moment.duration(ms).milliseconds();
min = (min < 10) ? "0" + min.toString() : min.toString();
sec = (sec < 10) ? "0" + sec.toString() : sec.toString();
ms = ms.toString().substring(0,2); // change this if you want to expand ms counter display
el.innerHtml = min + ":" + sec + "." + ms;
}, 50);
You're free to update the interval, and your milliseconds display without adjusting your calculations.

Why do I get +1 hour when calculating time difference in javascript?

I trying to create a very simple time difference calculation. Just "endtime - starttime". I'm getting +1 hour though. I suspect it has with my timezone to do, since I'm GMT+1.
Regardless, that should not affect the difference, since both start and end times are in the same timezone.
Check my running example-code here:
http://jsfiddle.net/kaze72/Rm3f3/
$(document).ready(function() {
var tid1 = (new Date).getTime();
$("#tid").click(function() {
var nu = (new Date).getTime();
var diff = new Date(nu - tid1);
console.log(diff.getUTCHours() + ":" +
diff.getUTCMinutes() + ":" +
diff.getUTCSeconds());
console.log(diff.toLocaleTimeString());
});
})
You must understand what Date object represent and how it stores dates. Basically each Date is a thin wrapper around the number of milliseconds since 1970 (so called epoch time). By subtracting one date from another you don't get a date: you just get the number of milliseconds between the two.
That being said this line doesn't have much sense:
var diff = new Date(nu - tid1);
What you really need is:
var diffMillis = nu - tid1;
...and then simply extract seconds, minutes, etc.:
var seconds = Math.floor(diffMillis / 1000);
var secondsPart = seconds % 60;
var minutes = Math.floor(seconds / 60);
var minutesPart = minutes % 60;
var hoursPart = Math.floor(minutes / 60);
//...
console.log(hoursPart + ":" + minutesPart + ":" + secondsPart);
Working fiddle.

Categories

Resources