Syncing server and client time in a javascript countdown script

I am working on a page that gets a date and time from an Access database and counts down until that date in real time using javascript (the seconds, minutes, etc. change without having to reload). My problem is that I need to count from the server time to the database date, not the client time. I am getting the server time by using ColdFusion. I tried to get the difference between the server and client time and subtract it from the client time but it skips seconds (I assume because the function is called every second and starts over again with the client time). Right now I have it so it starts out with the server time but then it goes back to the client time.

Can anyone help me, please? Here's what I have right now.


<cfoutput>

<cfset ServerDateTime = DateFormat(Now(), "MMM D, YYYY") & " " & TimeFormat(Now(), "HH:mm:ss")>

<script language="JavaScript">

count=1;

function setcountdown(theyear,themonth,theday,thehour,theminute,thesecond){
yr=theyear;mo=themonth;da=theday;hr=thehour,mn=theminute,sc=thesecond;
}

setcountdown(#Year(item.CloseDate)#,#Month(item.CloseDate)#,#Day(item.CloseDate)#,#Hour(item.CloseDate)#,#Minute(item.CloseDate)#,#Second(item.CloseDate)#)

var occasion="End!";
var message_on_occasion="<font color='red'><b>Auction has ended!</b></font>";

var countdownwidth='480px'
var countdownheight='20px'
var countdownbgcolor='lightblue'
var opentags='<font face="Verdana"><small>'
var closetags='</small></font>'

var montharray=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")
var crosscount=''

window.onload=countdown


function countdown(){

count++;

var today=new Date()
var todayServer=new Date("#ServerDateTime#")
if (count == 2)
{
var sec_difference = (todayServer.getTime() - today.getTime());
var today = (today.getTime() - sec_difference);
}
var today = new Date(today);


var todayy=today.getYear()
if (todayy < 1000)
todayy+=1900
var todaym=today.getMonth()
var todayd=today.getDate()
var todayh=today.getHours()
var todaymin=today.getMinutes()
var todaysec=today.getSeconds()
var todaystring=montharray[todaym]+" "+todayd+", "+todayy+" "+todayh+":"+todaymin+":"+todaysec
futurestring=montharray[mo-1]+" "+da+", "+yr+" "+hr+":"+mn+":"+sc
dd=Date.parse(futurestring)-Date.parse(todaystring)
dday=Math.floor(dd/(60*60*1000*24)*1)
dhour=Math.floor((dd%(60*60*1000*24))/(60*60*1000)*1)
dmin=Math.floor(((dd%(60*60*1000*24))%(60*60*1000))/(60*1000)*1)
dsec=Math.floor((((dd%(60*60*1000*24))%(60*60*1000))%(60*1000))/1000*1)
//if on day of occasion
if((dday<=0&&dhour<=0&&dmin<=0&&dsec<=1&&todayd==da) || dday<=-1){
if (document.layers){
mytimer = message_on_occasion;
}
else if (document.all||document.getElementById)
mytimer = message_on_occasion;
}

else{

if (dday == 0)
{
mytimer="<font color='red'>" + dhour + " hour(s), " + dmin + " minute(s), and " + dsec + " second(s)</font>";
}
else
{
mytimer="" + dday + " day(s), " + dhour + " hour(s), " + dmin + " minute(s), and " + dsec + " second(s) " + todayServer;
}
}


if (document.layers){
document.layers.AuctionTimer.document.write(mytimer)
document.layers.AuctionTimer.document.close()
}
else if (document.all)
{
AuctionTimer.innerHTML=mytimer
}
else if (document.getElementById)
{
document.getElementById("AuctionTimer").innerHTML=mytimer
}
setTimeout("countdown()",1000)

}



</script>

</cfoutput>


chsnrejectAsked:
Who is Participating?
 
TTomCommented:
<script>
mySeconds = 1800
myDays = parseInt(mySeconds/(60*60*24))
myHours = parseInt(mySeconds%(60*60*24)/(60*60))
myMins = parseInt((mySeconds%(60*60*24))%(60*60)/60)
mySecs = parseInt(((mySeconds%(60*60*24))%(60*60))%60)
alert(myDays + " days")
alert(myHours + " hours")
alert(myMins + " mins")
alert(mySecs + " secs")
</script>

See if this works for you.  I think it does it properly.

Tom
0
 
webwomanCommented:
Not going to happen. You don't control the client time -- and it's very likely NOT even close to your server time, nor should it be. I could be in Europe, you in the US, and I DO NOT want MY time to be set to yours. Besides, you don't have the power to do that.

In addition, the client time could be off, the clock date could be wrong, they could be on the other side of the dateline.

You can save the server time into javascript variables, and then use them on the client -- but don't take the time from the client and expect to match it on the server.

Don't even think of trying to get them to be consistent. It will NEVER happen. Even if you convert to GMT, it's STILL not going to sync.

Count using the server time if you have to match that. Forget the client time totally. And don't even consider trying to check them, because you might as well go play golf with Tiger Woods... it's a nice experience, but you've got NO chance of actually winning. ;-)

0
 
chsnrejectAuthor Commented:
I know it isn't close to the server time. All I am trying to do is count down solely from the server time, not the client time. Actually if I could dynamically sync the client and server time, I can adjust for time zone and other differences easily with Cold Fusion.

And yes, you can control the client time with JavaScript. Doing so does not actually change the clock, it changes what JavaScript returns as the client time (in other words, it just changes it on your page).

The reason I need to sync the client time with the server time is because I am creating an auction site. I can not have the countdown counting down to the client's time, it must be the server time.

If someone knows a better way to do a countdown with the server time without using the client time altogether, that would probably be better.
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
TTomCommented:
Seems to me that you could read the time from the server and determine how many seconds there are until the auction closes.  Pass that number down to the client and then use JS to do the countdown.

Am I missing something?

Tom
0
 
chsnrejectAuthor Commented:
That's what I was doing. The problem is that the JavaScript function is called every second to update the time and I can't get the server time again without reloading the page. Thanks for your input.
0
 
chsnrejectAuthor Commented:
0
 
TTomCommented:
Presumably, both the server and the client count seconds (or milliseconds) pretty much the same.  If the server counts down 50000 seconds, why would we assume that the client would not count down 50000 seconds in the same time?

If you pass down ONLY the number of seconds until the auction closes, you should not have any issue.  You can calculate the closing time for the auction by adding the number of seconds passed down to the current date.

I looked at your reference page, and the results were interesting.  When I reloaded the page, the number of minutes and seconds remaining changed, but, as soon as the JS was called, the countdown proceeded as I had expected.

The code, however, looked a bit complicated.

Tom
0
 
chsnrejectAuthor Commented:
When you first load the page it starts counting down from the server time (like I want), then when the JavaScript function executes it starts from the client time. Yes, the best way is to do math on the numbers instead of using time. I'm looking for a way to do this.
0
 
webwomanCommented:
Why do you need to count down at all? Check the time, display the server time and the time the auction closes, reload the page every 5 minutes until the difference is less than 5 minutes, than every minute until it's less than 1 minute, then every second -- maybe. And I wouldn't even bother, I'd just throw them a notice that the auction was ending in x minutes and the time it ends, the time zone it's in, and let them figure it out.

It's just too inaccurate, and you're leaving yourself open to lots of complaints when it doesn't work right for somebody who's waiting til the last second to make a bid.

What if they wait til the last minute and for whatever reason the connection goes down? Or there's a delay in the processing of the bid? I'd want to encourage people NOT to wait to the last minute, and in order to do that I wouldn't want to give them some kind of inaccurate stopwatch to look at...

Not to mention the load on the server of all those last minute bidders...and wouldn't it be just peachy if you had a big auction going on and your server crashed at the last second? Or some bidder got a 'server too busy' message when they tried to bid?
0
 
chsnrejectAuthor Commented:
Reloading the page every few seconds during the last minutes of an auction is not desirable to me. You lose valuable time just from reloading (especially if you have a slow connection). Actually I think most people would prefer a real-time countdown. Tricking the user would just make them angry and could produce inaccurate results. People are going to wait until the last minute, sometimes simply because that's when they discovered the item.
0
 
chsnrejectAuthor Commented:
Actually, as long as you program it right, it isn't inaccurate either.
0
 
TTomCommented:
What I fail to understand is how calculating a number of seconds on the server, sending that down to the client, and then beginning a countdown on the client can be "terribly" inaccurate.

The only thing that I can see which would affect it is latency (i.e., if the page takes more than a few seconds to load, the number will be a couple of seconds off).  I don't think there is really any way around that.

As far as the auction thing goes, I used to "haunt" a number of them, and I did get "server too busy" errors and problems getting a bid in "under the wire".  Those issues are a part of the process.  If you were sitting in an auction room and the auctioneer looked in the other direction at the close of the auction, you would be equally out of luck.

One of the best (and most frustrating) counters to this that I have seen is a system which extends the auction as long as there is continuous activity.  That way, no one gets "closed out" by their bid not being accepted.

Just adding my $.02,

Tom
0
 
chsnrejectAuthor Commented:
Tom, how would I convert the seconds to minutes, hours and days in JavaScript?
0
 
chsnrejectAuthor Commented:
Tom, how would I convert the seconds to minutes, hours and days in JavaScript?
0
 
TTomCommented:
mins = seconds/60
hours = seconds/(60*60)
days = seconds/(60*60*24)

var myTime = 2500000 //seconds
var myMinutes = myTime/60
var myHours = myTime/(60*60)
var myDays = myTime/(60*60*24)
0
 
chsnrejectAuthor Commented:
I had come up with a script earlier similar to yours. Now the problem is the hours. The hours will not be correct. I can only get the total hours.

An auction with 7 days, 31 minutes, and 3 seconds left, will have the hours 170. With a close date of 07/13/01 03:39 PM, the hours should be 2.

Unfortunately it doesn't look like I can do this without date/time functions. This was the source of my problem before....
0
 
chsnrejectAuthor Commented:
Thanks! It works perfectly. Webwoman, if I seemed irritated earlier in my replies I apologize, it was just frustration with my problem :)
0
 
webwomanCommented:
No problem... I know how frustrating these things can be. That's one of the reasons I throw out totally different alternatives and viewpoints -- sometimes it helps to completely rethink what you're doing (and why)
.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.