5
\$\begingroup\$

I've written a simple JavaScript function based off some existing code that takes a specific UNIX time string (in the snippet: 1491685200). It shows an alert if the specified time is still in the future. When that date has passed, it shows the elapsed days, hours and minutes whenever the function is called in-page.

I'm don't have much JavaScript object experience so it works just fine as-is, but I think it can be optimized further before I migrate my other stuff over to ES6.

function ElapsedTime () {
 var nTotalDiff = Math.round((new Date()).getTime() / 1000) - 1491685200;
 if (nTotalDiff >= 0) {
 var oDiff = {};
 oDiff.days = Math.floor(nTotalDiff / 86400);
 nTotalDiff -= oDiff.days * 86400;
 oDiff.hours = Math.floor(nTotalDiff / 3600);
 nTotalDiff -= oDiff.hours * 3600;
 oDiff.minutes = Math.floor(nTotalDiff / 60);
 nTotalDiff -= oDiff.minutes * 60;
 oDiff.seconds = Math.floor(nTotalDiff);
 return oDiff;
 } else {
 alert('nTotalDiff still not >=0, so must be before the specified date');
 }
}
function TimePassed() {
 oDiff = ElapsedTime();
 if(oDiff) {
 alert(oDiff.days + 'd ' + oDiff.hours + 'h ' + oDiff.minutes + 'm ');
 }
}
// document.getElementById('counter').addEventListener('click', TimePassed, false);
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Apr 8, 2017 at 19:23
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

Remarks to your code

  • Function names should be using camelCase.
  • Two minor formatting errors: function ElapsedTime (), if(oDiff).
    ↑ ↑
  • You mentioned ES6 in your question, so: var nTotalDiff could be declared using let and var oDiff using const.
  • You declare oDiff in TimePassed() as a global variable (you forgot var).
  • oDiff.seconds is declared, but never used.
  • (new Date()) can be written as new Date().
  • (削除) Specifying 1491685200 in human readable format would be better, I think. (削除ここまで)
    Update: suggestion removed due to the problem pointed out in the comment to this answer.
  • If you leverage power of modulo operator, you can get rid of all these nTotalDiff -= oDiff.██████ * ███.
  • alert(oDiff.days + 'd ' + oDiff.hours + 'h ' + oDiff.minutes + 'm ') can be written in ES6 using template literals as alert(`${oDiff.days}d ${oDiff.hours}h ${oDiff.minutes}m `), although space after m is unnecessary whatsoever.
  • Having two functions named ElapsedTime() and TimePassed() seem ambiguous.
  • Your code is not in strict mode.

My rewrite

const elapsedTime = () => {
 'use strict';
 const since = 1491685200000, // Saturday, 08-Apr-17 21:00:00 UTC
 elapsed = (new Date().getTime() - since) / 1000;
 if (elapsed >= 0) {
 const diff = {};
 diff.days = Math.floor(elapsed / 86400);
 diff.hours = Math.floor(elapsed / 3600 % 24);
 diff.minutes = Math.floor(elapsed / 60 % 60);
 diff.seconds = Math.floor(elapsed % 60);
 let message = `Over ${diff.days}d ${diff.hours}h ${diff.minutes}m ${diff.seconds}s.`;
 message = message.replace(/(?:0. )+/, '');
 alert(message);
 }
 else {
 alert('Elapsed time lesser than 0, i.e. specified datetime is still in the future.');
 }
};
document.getElementById('counter').addEventListener('click', elapsedTime, false);
<button id="counter">Check elapsed time</button>

Remarks

  • /(?:0. )+/ matches sequences of one or more zero followed by any character and a space. It is used to change potential output that would look like 0d 0h 0m 1s to simply 1s.
  • In message I added word over, because the calculated time is in fact the least amount of time that could have passed (calculation time, Math.floor(), instantaneous nature of time specification invalidation).
answered Apr 9, 2017 at 11:23
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Hi @Przemek, thanks for the remarks. However, the dateString you specified (Saturday, 08-Apr-17 21:00:00 UTC), without modification, didn't work (dashes between day/month/year, NaN) thus causing elapsed to always be <0. MDN recommends to just use a ISO8601 string (2017年04月08日 21:00:00Z) or a UNIX timestamp (1491685200000), dependent on user preference of course. \$\endgroup\$ Commented Apr 9, 2017 at 16:58
  • \$\begingroup\$ @rctgamer3: Hey there. Now that I have read a bit more deeply I have found that ISO8601 is indeed preferred over RFC2822, although I even found the following quote: because of the variances in parsing of date strings, it is recommended to always manually parse strings as results are inconsistent, especially across different ECMAScript implementations. As such I have edited the hardcoded 1491685200000 back in. I guess you learn something new everyday ;), thanks for the comment. \$\endgroup\$ Commented Apr 9, 2017 at 17:20

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.