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:
- Get the number of seconds separating the two dates by subtracting the future date's epoch time from today's epoch time.
- Divide the number of seconds by 604800 (the number of seconds in a week). Store the result as
weeks, and redefinesecondsas the remainder (which is what Ruby'sdivmoddoes). - Do the same thing for
days,hours, andminutes.
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 theweeks/days/hoursand then settingsecondsto the remainder. - I need to use
Math.floorbecause 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?
-
1Could not a debugger point out your mistake?Martin James– Martin James2015年06月01日 07:42:23 +00:00Commented Jun 1, 2015 at 7:42
1 Answer 1
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>