Count Down Closing Timer and dealing with DST in JavaScript

You can add these date prototypes to properly display the date and time in another location regardless of whether you are in DST or you or the destination observe DST

			Date.prototype.stdTimezoneOffset = function () {
				var jan = new Date(this.getFullYear(), 0, 1);
				var jul = new Date(this.getFullYear(), 6, 1);
				return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
			}

			Date.prototype.isDSTNow = function () {
				return this.getTimezoneOffset() < this.stdTimezoneOffset();
			}

			Date.prototype.isDSTObserved = function () {
				var jan = new Date(this.getFullYear(), 0, 1);
				var jul = new Date(this.getFullYear(), 6, 1);
				return jan.getTimezoneOffset() != jul.getTimezoneOffset();
			}

			Date.prototype.couldBeDST = function () {
				var d = new Date();
				var month = d.getMonth();
				var day = d.getDate();
				var dow = d.getDay();
				var previousSunday = day - dow;
				// January, February, and December are out.
				if (month < 3 || month > 11) { return false; }
				// April throuh October is in.
				if (month > 3 && month < 11) { return true; } // In March, we are DST if our previous sunday was on or after the 8th. if (month == 3) { return previousSunday >= 8; }
				// In November we must be before the first Sunday to be DST.
				// That means the previous Sunday must be in the previous month
				// aka less than/before the 1st.
				return previousSunday < 1;
			}

Full Code
This example takes an hours array with unique IDs and TZ info about a location and uses the current information to update the appropriate on screen timer every 1 second.

 
jQuery( document ).ready(function($) {
	var now = new Date();
	var weekday = new Array(7);
	var isOpen = function(hours,currentTime,offsetHours,locationHasDST,isDST,hasDSTLocal,couldBeDST){
			var result = false;
			if (hours == '') {
				return false;
			} else {
				hours.forEach( function(hourSet) {
					splitHours = hourSet.split(',');
					var isoDate = new Date(currentTime.getTime() - (currentTime.getTimezoneOffset() * 60000)).toISOString();
					var open = new Date(isoDate.substring(0, 10) + ' ' + splitHours[0]);
					var close = new Date(isoDate.substring(0, 10) + ' ' + splitHours[1]);
					var offsetSec = ( offsetHours * 60 * 60 ) + ( currentTime.getTimezoneOffset() * 60 );
					if (locationHasDST && !hasDSTLocal && couldBeDST) {	
						// eg Looking at EDT from AZ/MST
						// This is the one case here isDST and couldBeDST are not equal
						offsetSec = offsetSec - 3600;
					} else if (!locationHasDST && isDST && hasDSTLocal) {
						// Looking at EDT from AZ/MST 3 = (5) + (-7) + 1. So I need to take 3 more hours to count down timer.
						offsetSec = offsetSec + 3600;
					}

					if ((open.getTime() < (currentTime.getTime() + offsetSec*1000)) && ((currentTime.getTime() + offsetSec*1000 ) < close.getTime()))  {
						result = ((close.getTime() - currentTime.getTime())/1000) - offsetSec;
					}
				});
				return result;
			}
		}
	var checkTime = function(hours,offsetHours,locationHasDST) {
			Date.prototype.stdTimezoneOffset = function () {
				var jan = new Date(this.getFullYear(), 0, 1);
				var jul = new Date(this.getFullYear(), 6, 1);
				return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
			}

			Date.prototype.isDSTNow = function () {
				return this.getTimezoneOffset() < this.stdTimezoneOffset();
			}

			Date.prototype.isDSTObserved = function () {
				var jan = new Date(this.getFullYear(), 0, 1);
				var jul = new Date(this.getFullYear(), 6, 1);
				return jan.getTimezoneOffset() != jul.getTimezoneOffset();
			}

			Date.prototype.couldBeDST = function () {
				var d = new Date();
				var month = d.getMonth();
				var day = d.getDate();
				var dow = d.getDay();
				var previousSunday = day - dow;
				// January, February, and December are out.
				if (month < 3 || month > 11) { return false; }
				// April throuh October is in.
				if (month > 3 && month < 11) { return true; } // In March, we are DST if our previous sunday was on or after the 8th. if (month == 3) { return previousSunday >= 8; }
				// In November we must be before the first Sunday to be DST.
				// That means the previous Sunday must be in the previous month
				// aka less than/before the 1st.
				return previousSunday < 1; } var now = new Date(); var isDST = now.isDstObserved(); var today = weekday[now.getDay()]; var dayOfWeek = now.getDay(); var hour = now.getHours(); var minutes = now.getMinutes(); var today = weekday[now.getDay()]; //add AM or PM var suffix = hour >= 12 ? "PM" : "AM";

			// add 0 to one digit minutes
			if (minutes < 10) {
				minutes = "0" + minutes
			};
			
			hour = ((hour + 11) % 12 + 1); //i.e. show 1:15 instead of 13:15

			for (var curPostID in inHours ) {
				// Assign the needed variables while in scope.
				var timeDiv = document.getElementById('timeDiv-' + curPostID);
				var hours = inHours[curPostID][today];
				var offsetHours = inOffsetHours[curPostID];
				var hasDST = inObservesDST[curPostID]  == "yes";
				secondsLeft = isOpen(hours,now,offsetHours,hasDST,isDST);
				if (secondsLeft) {
					ooc = 'open';
					hours=Math.floor(secondsLeft/3600);
					min=Math.floor(secondsLeft/60)-hours*60;
					seconds=Math.floor(secondsLeft%60);
					var closingTime = hours + ':' + ("0" + min).slice (-2) + ':' + ("0" + seconds).slice (-2);

					timeDiv.innerHTML = 'YOUR MESSAGE';
				} else {
					ooc = 'closed';
					var closingIn = '(800) 288-1407';
					timeDiv.innerHTML = 'YOUR MESSAGE';
				}
				timeDiv.className = "timeDiv " + ooc;
				timeDiv.style.display = "block";
			}
			
		};

	/* MAIN CODE SECTION EXECUTED ON READY */
	// Populate the Weekday variable
	weekday[0] = "sunday";
	weekday[1] = "monday";
	weekday[2] = "tuesday";
	weekday[3] = "wednesday";
	weekday[4] = "thursday";
	weekday[5] = "friday";
	weekday[6] = "saturday";

	var posts = arrVars["arrHours"];

	for (var curPostID in posts ) {
		var currentDay = weekday[now.getDay()];
		var currentDayID = "#" + currentDay + '-' + curPostID; //gets todays weekday and turns it into id

		// All of the setup is now complete.  Now do the work.

		$(currentDayID).toggleClass("today"); //hightlights today in the view hours modal popup

		var iDay;
		var i=10;
		for (iDay = 0; iDay < 7; iDay++) { var loopDay = weekday[iDay]; var loopDayTimeDiv = "#" + loopDay + '-' + curPostID + ' div.time'; var loopHours = arrVars["arrHours"][curPostID][loopDay]; if (loopHours == '') { hoursString = "Closed"; } else { var hoursString = ''; loopHours.forEach(function(hoursSet){ hoursSet = hoursSet.replace(/ AM/g,'am'); hoursSet = hoursSet.replace(',',' - '); hoursSet = hoursSet.replace(/ PM/g,'pm'); if (hoursString > '') hoursString += '
';
				hoursString += hoursSet;
				});
			}
			$(loopDayTimeDiv).html(hoursString);
		}

	}

	setInterval( function(){
			checkTime(arrVars["arrHours"],arrVars["offsetHours"],arrVars["observesDST"])
		}, 1000);

});

});

Add a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.