Reputation: 113
I have been using a javascript that I found on the interwebz to calculate the time left for a specific date/time including it's timezone. The script has worked just fine (much thanks to this community) up until now.
As I have been counting down to the 10th of November 2015 the script has been working correct, until today, when it somehow added a whole months worth of days for no reason. But if i change the month to december or january the script works just fine.
As of today, the 31st of October, the script says that it is 40 days left until the 10th of November, and I really cant wrap my head around why? And as I mentioned earlier, the script had been working just fine until today.
Is there anyone out there that can explain why it behaves like this, and how to fix it?
Update: As soon as my local time hit 00:00 (01/11/2015), the countdown changed from 39 days to 9 days.
Update 2: If i change my local date to the 31st of December, and counting down to the 10th of January, the same issue occurs. But if I change my local date to the 30th of November, and counting down to the 10th December, the issue does NOT occur. So the issue seems to be isolated to the 31st of any month.
The full (modified) script below:
<!--Copy and paste just above the close </BODY> of you HTML webpage.-->
<SCRIPT type="text/javascript">
// **** Time Zone Count Down Javascript **** //
/*
Visit http://rainbow.arch.scriptmania.com/scripts/
for this script and many more
*/
////////// CONFIGURE THE COUNTDOWN SCRIPT HERE //////////////////
var month = '11'; // '*' for next month, '0' for this month or 1 through 12 for the month
var day = '10'; // Offset for day of month day or + day
var hour = 14; // 0 through 23 for the hours of the day
var tz = -5; // Offset for your timezone in hours from UTC
var lab = 'tzcd'; // The id of the page entry where the timezone countdown is to show
function start() {displayTZCountDown(setTZCountDown(month,day,hour,tz),lab);}
// ** The start function can be changed if required **
window.onload = start;
////////// DO NOT EDIT PAST THIS LINE //////////////////
function setTZCountDown(month,day,hour,tz)
{
var toDate = new Date();
if (month == '*')toDate.setMonth(toDate.getMonth() + 1);
else if (month > 0)
{
if (month <= toDate.getMonth())toDate.setFullYear(toDate.getFullYear() + 1);
toDate.setMonth(month-1);
}
if (day.substr(0,1) == '+')
{var day1 = parseInt(day.substr(1));
toDate.setDate(toDate.getDate()+day1);
}
else{toDate.setDate(day);
}
toDate.setHours(hour);
toDate.setMinutes(0-(tz*60));
toDate.setSeconds(0);
var fromDate = new Date();
fromDate.setMinutes(fromDate.getMinutes() + fromDate.getTimezoneOffset());
var diffDate = new Date(0);
diffDate.setMilliseconds(toDate - fromDate);
return Math.floor(diffDate.valueOf()/1000);
}
function displayTZCountDown(countdown,tzcd)
{
if (countdown < 0) document.getElementById(tzcd).innerHTML = "Sorry, you are too late.";
else {var secs = countdown % 60;
if (secs < 10) secs = '0'+secs;
var countdown1 = (countdown - secs) / 60;
var mins = countdown1 % 60;
if (mins < 10) mins = '0'+mins;
countdown1 = (countdown1 - mins) / 60;
var hours = countdown1 % 24;
var days = (countdown1 - hours) / 24;
document.getElementById(tzcd).innerHTML = days + " day" + (days == 1 ? '' : 's') + ' + ' +hours+ 'h : ' +mins+ 'm : '+secs+'s';
setTimeout('displayTZCountDown('+(countdown-1)+',\''+tzcd+'\');',999);
}
}
</SCRIPT>
<p><font face="arial" size="-2">The countdown script at </font><br><font face="arial, helvetica" size="-2"><a href="http://rainbow.arch.scriptmania.com/scripts/">Rainbow Arch</a></font></p>
Upvotes: 3
Views: 421
Reputation: 65034
The date calculation code has a bug in it which means it doesn't work correctly when run on the 31st of the month.
Here's the code that runs when counting down to 10 November when run on 31 October; I've cut out all code in if
statements that don't run:
var month = '11';
var day = '10';
var toDate = new Date();
toDate.setMonth(month-1);
toDate.setDate(day);
Why did the countdown timer show 40 days to 10 November from 31 October? Let's step through the code above:
var toDate = new Date();
At this point, toDate
is 31 October 2015.
toDate.setMonth(month-1);
month-1
is 10, which represents November. This would set toDate
to 31 November 2015, but that date does not exist. The JavaScript Date object handles invalid dates off the end of a month by 'rolling' them forward to the next month. So after this line, toDate
has the value 1 December 2015.
toDate.setDay(day);
Finally, toDate
ends up with 10 December 2015. This is 40 days on from 31 October 2015.
Instead of calling setFullYear()
, setMonth()
and setDate()
individually, it is better to collect all the values together and then create a Date
object from all of these values in one go. This avoids a Date object having an invalid intermediate value during the date calculations.
I would recommend replacing the following code within the function setTZCountDown
,
var toDate = new Date();
if (month == '*')toDate.setMonth(toDate.getMonth() + 1);
else if (month > 0)
{
if (month <= toDate.getMonth())toDate.setFullYear(toDate.getFullYear() + 1);
toDate.setMonth(month-1);
}
if (day.substr(0,1) == '+')
{var day1 = parseInt(day.substr(1));
toDate.setDate(toDate.getDate()+day1);
}
else{toDate.setDate(day);
}
with the following:
var now = new Date();
var countdownToYear = now.getFullYear();
var countdownToMonth = now.getMonth();
var countdownToDay = now.getDate();
if (month === '*') {
countdownToMonth += 1;
} else if (month > 0) {
if (month <= now.getMonth()) {
countdownToYear += 1;
}
countdownToMonth = month - 1;
}
if (day.substr(0,1) === '+') {
var day1 = parseInt(day.substr(1), 10);
countdownToDay += day1;
} else {
countdownToDay = day;
}
var toDate = new Date(countdownToYear, countdownToMonth, countdownToDay);
Upvotes: 1