I have a function that takes a time of minutes and seconds, and converts it to a string in the following way: '0:30' would become '30 Seconds', '1:30' would become '1 minute 30 seconds', '2:01' would become '2 minutes 1 second', etc. My function works fine, but I'm wondering if there are areas for improvement.
function formatTime(formattedTime) {
let minStr, secStr;
let minNum = formattedTime.split(':')[0];
let secNum = formattedTime.split(':')[1];
if (minNum === '1') {
minStr = 'minute';
} else {
minStr = 'minutes';
}
if (secNum === '01') {
secStr = 'second';
secNum = '1';
} else {
secStr = 'seconds';
}
if (minNum === '0') {
return `${secNum} ${secStr}`;
} else if (secNum === '00') {
return `${minNum} ${minStr}`;
} else {
return `${minNum} ${minStr} ${secNum} ${secStr}`;
}
}
1 Answer 1
I made a few changes to the function that I think improve readability. By using parseInt()
on the seconds, I eliminated the need to later set the secNum
from 01
to 1
. Since we no longer need to change that, the minStr
and secStr
can be set with a ternary operator. I also used destructuring to clean up the splitting of the time.
To make it less error prone, you'd also want to make sure to do some sanity checks on the input, as mentioned in the comments.
All told, it ended up looking like this:
// Tests
console.log(formatTime('1:00'))
console.log(formatTime('1:01'))
console.log(formatTime('1:30'))
console.log(formatTime('0:30'))
console.log(formatTime('bad data'))
function formatTime(formattedTime) {
// Set up minutes and seconds
const [match, minNum, secNum] = formattedTime.match(/(\d+):(\d+)/) || [];
// Make sure we're getting the data in correct
if(!match) return false;
// Get the correct minutes and seconds strings
let minStr = (minNum === '1') ? 'minute' : 'minutes'
let secStr = (parseInt(secNum) === 1) ? 'second' : 'seconds'
// Return the formatted time
if (parseInt(minNum) === 0) {
return `${secNum} ${secStr}`;
} else if (parseInt(secNum) === 0) {
return `${minNum} ${minStr}`;
} else {
return `${minNum} ${minStr} ${parseInt(secNum)} ${secStr}`;
}
}
This is making use of some ES6 additions, so if you want good browser support you'll need to make sure to run this through Babel.
-
3\$\begingroup\$ damn, i was gonna write an answer but i got caught up in work stuff.. the only thing I was gonna say that you didn't mention is to sanitize the input..
if(!formattedTime.match(/\d+:\d+/)) return false;
\$\endgroup\$I wrestled a bear once.– I wrestled a bear once.2018年01月05日 21:03:22 +00:00Commented Jan 5, 2018 at 21:03 -
2\$\begingroup\$ @le_m Good point on the extraneous declaration for
minStr
andsecStr
, updated! \$\endgroup\$Matthew Johnson– Matthew Johnson2018年01月05日 21:15:18 +00:00Commented Jan 5, 2018 at 21:15 -
2\$\begingroup\$ beware of using
parseInt()
without passing the radix.... "If the input string begins with "0", radix is eight (octal) or 10 (decimal). Exactly which radix is chosen is implementation-dependent. ECMAScript 5 specifies that 10 (decimal) is used, but not all browsers support this yet." \$\endgroup\$2018年01月05日 22:29:00 +00:00Commented Jan 5, 2018 at 22:29 -
2\$\begingroup\$ Looks good. Just a couple of questions: why use let instead of const? why parseInt the seconds but not the minutes? \$\endgroup\$tokland– tokland2018年01月06日 00:31:49 +00:00Commented Jan 6, 2018 at 0:31
-
1\$\begingroup\$ @le_m I thought I removed that redundancy, but apparently not. Stripped that out. \$\endgroup\$Matthew Johnson– Matthew Johnson2018年01月08日 15:06:38 +00:00Commented Jan 8, 2018 at 15:06
Explore related questions
See similar questions with these tags.
minNum
is easily confused with "minimum number", why not simply writeminutes
instead? \$\endgroup\$minutes = 'minutes'
\$\endgroup\$