My translation from Ruby to JavaScript gives different results
I am writing a function that takes a future date and returns a string in the form "X weeks, Y days, Z hours"
representing a countdown to that date. My approach:
- Get the number of seconds separating two dates by subtracting the epoch time of the future date from today.
- Divide the number of seconds by 604800 (number of seconds per week). Save the result as
weeks
and overrideseconds
as remainder (which is what Ruby doesdivmod
). - Do the same for
days
,hours
andminutes
.
I first 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 is missing
divmod
, I did it manually, first settingweeks
/days
/hours
and then settingseconds
to the remainder. - I need to use
Math.floor
because JavaScript exclusively uses floats. - I am dividing the epoch time by 1000 because JS uses milliseconds for its timestamps, unlike Ruby.
- The My JS function expects to receive an integer epochTime since I haven't learned how to pass arbitrary arguments in JS.
Code:
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.";
}
As 2015,6,19
of June 1st, JS gives "6 weeks, 5 days, 21 hours"
and Ruby gives "2 weeks, 3 days, 6 hours"
. I cannot figure out where this difference is. Can anyone point out my mistake?
source to share
However, if I feed the date 2015,6,19 for both functions, it will be June 1st, when 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 do this, but I am assuming you do:
timeCountdown(new Date(2015, 6, 19));
... but in JavaScript month numbers start at 0, not 1, so June is month 5 and 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>
source to share