For many shareware developers, when an application is first run, you want to check the date and then set a timeout based on that first date. But what if the user sets their clock ahead a year before the first run? If you have a 7 day trial period and you are hard coded to that first run date, if the user resets their clock when subsequently running your application, their trial period is effectively 1 year + 7 days. To avoid this, you can use the following code to determine if their clock is correct. It requires an internet connection but you could use the code in such a way that if there is no connection and you are unable to verify the clock, then tell your app to quit without marking the first run.
The code allows you to return the adjusted correct date or to simply return a boolean if the system clock is within an allowable offset (in the code below this offset is 2 hours: if the system time is within 2 hours (on either side) of the correct date, the clock is deemed to be correct).
Here’s the code:
--NIST time servers: <http://tf.nist.gov/service/time-servers.html>
property time_servers : {"time-a.nist.gov", "time-b.nist.gov", "time-a.timefreq.bldrdoc.gov", "time-b.timefreq.bldrdoc.gov"}
property allowable_offset : (2 * hours) --if the clock is within correct time ± allowable_offset, return true
property the_timeout : 30 --seconds
my clock_is_correct(true)
-->date "Tuesday, November 29, 2005 5:31:39 PM"
my clock_is_correct(false)
-->true
on clock_is_correct(return_adjusted_date)
set e to "could not determine"
repeat with i from 1 to (count time_servers)
set the_address to (item i of time_servers)
try
with timeout of the_timeout seconds
if (my ping_address(the_address)) then
set the_offset to (do shell script "ntpdate -q " & the_address)'s paragraph -1
set the_offset to (text ((offset of "offset" in the_offset) + 7) thru -5 of the_offset) as real
if return_adjusted_date then return (current date) + the_offset
return ((the_offset < allowable_offset) and (the_offset > (allowable_offset * -1)))
end if
end timeout
on error e
end try
end repeat
return e
end clock_is_correct
on ping_address(the_address)
if the_address does not contain "://" then set the_address to "http://" & the_address
((the_address as URL)'s host & {dotted decimal form:""})'s dotted decimal form ≠""
end ping_address
Jon