-2

In a web game I am trying to display remaining time in HH:MM:SS format -

screenshot

by using the following code (the backend sends remaining epoch timestamps as game.expire1 and game.expire2 via Websockets):

var expireDiv1 = $('#expire1');
var expireDiv2 = $('#expire2');

setInterval(function() { 

    var now = Math.floor(new Date().getTime() / 1000);
    var left1 = game.expire1 - now;
    var left2 = game.expire2 - now;

    if (left1 > 0) {
            var hh1 = Math.floor(left1 / 60 / 60) % 60;
            var mm1 = Math.floor(left1 / 60) % 60;
            var ss1 = left1 % 60;

            expireDiv1.html(
                    hh1 + 
                    (mm1.length > 1 ? ':' : ':0') + // DELIMITER; DOES NOT WORK
                    mm1 + 
                    (ss1.length > 1 ? ':' : ':0') + // DELIMITER; DOES NOT WORK
                    ss1);
    } else {
            expireDiv1.html('');
    }

    if (left2 > 0) {
            var hh2 = Math.floor(left2 / 60 / 60) % 60;
            var mm2 = Math.floor(left2 / 60) % 60;
            var ss2 = left2 % 60;

            expireDiv2.html(
                    hh2 + 
                    (mm2.length > 1 ? ':' : ':0') + // DELIMITER; DOES NOT WORK 
                    mm2 + 
                    (ss2.length > 1 ? ':' : ':0') + // DELIMITER; DOES NOT WORK
                    ss2);
    } else {
            expireDiv2.html('');
    }
}, 1000);

As you can see above, my naive trick is to set the delimiters between hours, minutes and seconds to ':' or ':0' depending on the string length -

(ss1.length > 1 ? ':' : ':0') 

However this does not work as expected, because ss1.length returns undefined instead of 1 or 2 which I was expecting (I thought Javascript would cast my integer number of seconds to a string?)

What would you recommend here please as a most portable workaround?

Alexander Farber
  • 18,345
  • 68
  • 208
  • 375
  • The value of *mm2* is not changed to type string, it is the result of the expression that is a string. So in the comparison `mm2.length > 1` *mm2* is a number, and numbers don't have a *length* property. – RobG Feb 06 '18 at 20:53

3 Answers3

2

The variables you're checking the .length property of are numbers, this kind of variables don't have that property. What you could do instead of val.length > 1 is val > 9.

Titus
  • 20,544
  • 1
  • 19
  • 29
1

How about

(ss1 >= 10 ? ':' : ':0')

Also see Pad a number with leading zeros in JavaScript for more options.

nvioli
  • 3,854
  • 3
  • 16
  • 33
1

Date object has method to get hour, minutes and seconds. You can put them into an array, add 0 if necessary and call join method to concat array into string with ":" separator,

 var left1 = new Date(/*game.expire1 - now*/);

 var left1hours = left1.getHours();
 var left1minutes = left1.getMinutes();
 var left1seconds = left1.getSeconds();

 var timeArray = [left1hours, left1minutes, left1seconds].map(function (l1) {
  return (l1<10)? "0"+l1 : l1;
 })

 console.log(timeArray.join(":"))

This is a function version, same logic I just made it more compact.

 function timestampToHMMSS(ts) {
 
  return ["getHours", "getMinutes", "getSeconds"]
   .map(function(s) {
    return (new Date(ts))[s]();
   })
   .map(function (t) {
    return (t<10)? "0"+t : t;
   })
   .join(":");
 }
 
 console.log(timestampToHMMSS(new Date()));
 console.log(timestampToHMMSS(1517948038*1000));
Peter
  • 1,586
  • 13
  • 25