3

I'm writing a function that accepts a future date and returns a string in the form "X weeks, Y days, Z hours" representing the countdown to that date. My approach is:

  1. Get the number of seconds separating the two dates by subtracting the future date's epoch time from today's epoch time.
  2. Divide the number of seconds by 604800 (the number of seconds in a week). Store the result as weeks, and redefine seconds as the remainder (which is what Ruby's divmod does).
  3. Do the same thing for days, hours, and minutes.

First I wrote it in Ruby, which works:

def time_countdown(*date_string)
 seconds = Time.new(*date_string).to_i - Time.now.to_i
 weeks, seconds = seconds.divmod 604800
 days, seconds = seconds.divmod 86400
 hours, seconds = seconds.divmod 3600
 minutes, seconds = seconds.divmod 60
 return "#{weeks} weeks, #{days} days, #{hours} hours." 
end

I translated this to JavaScript with the same approach except for the following:

  • Since JavaScript lacks divmod, I did that manually, first setting the weeks/days/hours and then setting seconds to the remainder.
  • I need to use Math.floor because JavaScript exclusively uses floats.
  • I divide the epoch times by 1,000 since JS uses milliseconds for its epoch timestamps unlike Ruby.
  • My JS function expects to receive an epochTime integer since I haven't learnt how to pass around arbitrary-length argument lists in JS.

The code is:

function timeCountdown(epochTime) {
 var seconds = epochTime/1000 - new Date().getTime() / 1000;
 var weeks = Math.floor(seconds / 604800);
 seconds = seconds % 604800;
 var days = Math.floor(seconds / 86400);
 seconds = seconds % 86400;
 var hours = Math.floor(seconds / 3600);
 seconds = seconds % 3600;
 return weeks + " weeks, " + days + " days, " + hours + " hours.";
}

For the date 2015,6,19, as of June 1st, JS gives "6 weeks, 5 days, 21 hours" and Ruby gives "2 weeks, 3 days, 6 hours". I can't figure out where this difference arises. Could someone point out my mistake?

sawa
169k51 gold badges288 silver badges401 bronze badges
asked Jun 1, 2015 at 7:36
1
  • 1
    Could not a debugger point out your mistake? Commented Jun 1, 2015 at 7:42

1 Answer 1

2

Yet if I feed the date 2015,6,19 to both functions, it being June 1st as I write this, JS tells me 6 weeks, 5 days, 21 hours and Ruby tells me 2 wweeks, 3 days, 6 hours.

You haven't shown how you're doing that, but my guess is you're doing:

timeCountdown(new Date(2015, 6, 19));

...but in JavaScript, month numbers start with 0, not 1, so June is month 5, not 6:

timeCountdown(new Date(2015, 5, 19));
// --------------------------^

Example:

function timeCountdown(epochTime) {
 var seconds = epochTime/1000 - new Date().getTime() / 1000;
 var weeks = Math.floor(seconds / 604800);
 seconds = seconds % 604800;
 var days = Math.floor(seconds / 86400);
 seconds = seconds % 86400;
 var hours = Math.floor(seconds / 3600);
 seconds = seconds % 3600;
 return weeks + " weeks, " + days + " days, " + hours + " hours.";
}
snippet.log("July 19th: " + timeCountdown(new Date(2015, 6, 19)));
snippet.log("June 19th: " + timeCountdown(new Date(2015, 5, 19)));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

answered Jun 1, 2015 at 7:46
Sign up to request clarification or add additional context in comments.

1 Comment

You're exactly right, that's what I was doing. I had no idea that JS used zero-indexed numbers for this and it didn't even occur to me. Thanks a ton, completely solved.

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.