Reputation: 33655
I bit of a puzzle to solve in CF here.
You have a timestamp passed as an argument to the server. For example 2012-5-10 14:55
.
How would you see if 30 seconds has passed from the time given and return true
or false
?
Rules:
You cannot use the current server time to check if 30 seconds have passed because the timestamp comes from anywhere in the world and will always be wrong.
In this case you can always trust the argument timestamp passed to the server.
How would this be possible in ColdFusion 9 (if at all)?
Upvotes: 2
Views: 354
Reputation: 2163
You don't specify if the argument passed to the server is a API request, form submit or an ajax request, etc, so there will be differences in the implementation on the other end. However, the ColdFusion server end should be extremely similar and is basically bound with 3 issues; timezones, time disparity, and latency.
To solve the timezone issue you can require the argument to be passed as UTC time. When comparing the times with Coldfusion you would do something like:
<cfif DateDiff("s", Variables.PassedTimestamp, DateConvert( "Local2UTC", Now() )) EQ 30>
<!--- Exactly 30 seconds difference between timestamps --->
</cfif>
But you don't know if the time sent to you is synchronized with the time on your server. To help with this you can provide a method for the other end to query your time and either adjust their time accordingly or to echo back your time with their own time.
That time synching and the originally discussed send of the timestamp will both suffer from latency. Any communication over a network will suffer from latency, just varying levels of latency. Location and Internet connection type can have more of an impact than protocol type. You could do something like pinging the other end to get the response time and then halving that and adding it to the timestamp, but that's still an aproximation and not all servers will respond to a ping.
Additionally, the code on your server and the other end will also introduce latency. To reduce this you want the other end to calculate the timestamp as close to the end of the request as possible, and your code to calculate the timestamp as soon as possible. This can be done with ColdFusion by setting the request time as near the top of you Application.cfm|cfc as possible.
<cfset Request.Now = Now()>
And then change the checking code to:
DateDiff("s", Variables.PassedTimestamp, DateConvert( "Local2UTC", Request.Now ))
If, instead, you're wanting to loop until 30 seconds has passed and then respond, note that your response won't appear to happen after 30 seconds because the latency will delay the response going back to the other end.
Getting exactly 30 seconds is impossible, but you take steps that will get your closer. If you're just needing to see if approximately 30 seconds has passed, then that will be good enough.
Upvotes: 1
Reputation: 7193
Hmmm.... Your problem is that you don't know the latency. You can count 30 seconds from the time you receive the timestamp - but that could be seconds after the time stamp was created.
You can count 30 seconds easily enough with...
sleep(30000); //1000 miliseconds = 1 second. 30k = 30 seconds
So as soon as you get the var you could "wait" for thirty seconds and then do something. But from your question it seems like you need exact 30 seconds from the time the timestamp (created on the client) was created. You probably cannot be that exact because:
If you can dictate an HTML5 browser you could use websockets for this - it's practically begging for it :) But that's the only real solution I can think of.
Upvotes: 3