Today we embark upon a journey into the wide world of helper functions, aka the things you probably never think about because you just import them from lodash or whatnot.
Let's say you're building a video UI, and you know you'll be getting video data from the server. That data will be an object with properties like:
{
name: 'Great video!',
thumbnail: 'nice-thumbnail.jpg',
videoSource: 'video-file.mp4',
durationInSeconds: 403,
...
}
You want to show the duration on a pretty overlay, but to do that you need to go from the durationInSeconds
to a more readable HH:MM:SS
format. You could accomplish this with the moment
library, but in order to do that you'd have to require
all of moment
, which is a little heavy for just this one operation.
Enter this beautiful one-liner to get from seconds to HH:MM:SS (Hat tip to Stack Overflow users Harish Anchu and Frank):
const formatSecondsAsHHMMSS = valueInSeconds =>
new Date(valueInSeconds * 1000).toISOString().substr(11, 8);
To dig into this function a bit, what we're doing is as follows:
Date
constructor traffics in millisecondssubstr
function.That's a great start, but there's also room to iterate here. For example, maybe you don't want to show a leading zero:
const formatSecondsAsHHMMSS = valueInSeconds => {
const result = new Date(valueInSeconds * 1000).toISOString().substr(11, 8);
if (result.charAt(0) === '0') return result.substr(1);
return result;
};
formatSecondsAsHHMMSS(403);
// --> "0:06:43"
Or you could tweak the substr
to send back just MM:SS:
const formatSecondsAsMMSS = valueInSeconds =>
new Date(valueInSeconds * 1000).toISOString().substr(14, 5);
formatSecondsAsMMSS(403);
// --> "06:43"
Or you could tweak it to send back just MM:SS if hours is 0:
const formatSecondsAsHHMMSSWithTrimming = valueInSeconds => {
const result = new Date(valueInSeconds * 1000).toISOString().substr(11, 8);
if (result.substr(0, 3) === '00:') return result.substr(3);
return result;
};
formatSecondsAsHHMMSSWithTrimming(403);
// --> "06:43"
formatSecondsAsHHMMSSWithTrimming(13403);
// --> "03:43:23"
Or you could recursively check for zeroes and trim them all off:
const formatSecondsAsHHMMSSWithRecursiveTrimming = valueInSeconds => {
let result = new Date(valueInSeconds * 1000).toISOString().substr(11, 8);
while (result.charAt(0) === '0' || result.charAt(0) === ':')
result = result.substr(1);
return result;
};
formatSecondsAsHHMMSSWithRecursiveTrimming(403);
// --> "6:43"
formatSecondsAsHHMMSSWithRecursiveTrimming(13403);
// --> "3:43:23"
Each of these serves a different use case, and depending on your implementation one or the other will make the most sense. Maybe you'll want to pass in an options
argument to allow this nice helper function to be as flexible as you please:
const formatSecondsAsHHMMSSWithOptions = (
valueInSeconds,
options = { trimLeadingZeroes: false }
) => {
let result = new Date(valueInSeconds * 1000).toISOString().substr(11, 8);
if (options.trimLeadingZeroes) {
while (result.charAt(0) === '0' || result.charAt(0) === ':')
result = result.substr(1);
}
return result;
};
formatSecondsAsHHMMSSWithOptions(403);
// --> "00:06:43"
formatSecondsAsHHMMSSWithOptions(403, {
trimLeadingZeroes: true,
});
// --> "6:43"
I could go on like this, but maybe we'll stop there for today. The point is... well, I'm not sure what the point is, but I think it has something to do with learning being fun. Which it is! So, bye-bye for now, see you next time. ⏱