2005 ColdFusion UDF To Access NIST Time Servers
A developer asked me how he could get absolutely accurate time information for an application that he is working on. He cannot rely on local server time as he has no control over the machine, and can't verify that it is accurate (and can't change the time if not). There is no NTP (network time protocol) tag in ColdFusion, but fortunately one is not needed, because the NIST time servers also respond to plain text daytime protocol requests.
Here is a quick UDF I threw together to solve the problem. Call GetNISTTime() and it'll return a structure containing the raw data returned from the time server, as well as individual fields broken out for ease of use:
1<!---
2
3Name: GetNISTTime()
4
5Author: Ben Forta, 12/6/2005
6
7Description: Obtains current time data from NIST
8 Internet Time Service servers.
9
10 DST: US daylight savings time flag.
11 HEALTHY: TRUE if time server is healthy, FALSE if not.
12 JULIAN: Last 5 digits of Julian date/time value.
13 LEAPMONTH: TRUE is second will be added to or subtracted
14 from the current month.
15 MSADV: Number of milliseconds advanced by server to
16 compensate for network latency.
17 NOW: Current date/time.
18 RAW: Raw data from time server.
19 SUCCESS: TRUE if worked, FALSE if not, check
20 this flag first.
21
22Note: For a list of NIST time servers see:
23 http://tf.nist.gov/timefreq/service/time-servers.html
24 Servers should be addressed via IP address rather than
25 host name. The server used here is time.nist.gov
26 (192.43.244.18), but any of the listed servers will work.
27 To use an alternate server, just specify the IP
28 address in timeServer variable.
29--->
30
31<cffunction name="GetNISTTime" returntype="struct" output="false">
32 <cfset var timeServer="192.43.244.18">
33 <cfset var result=StructNew()>
34
35 <!--- Try/catch block --->
36 <cftry>
37
38 <!--- Try get time data --->
39 <cfhttp url="http://#timeServer#:13/" />
40 <!--- Save raw data --->
41 <cfset result.raw = CFHTTP.FileContent>
42 <!--- Extract Julian date --->
43 <cfset result.julian=ListGetAt(result.raw, 1, " ")>
44 <!--- Extract current date and time --->
45 <cfset result.now=ParseDateTime(ListGetAt(result.raw, 2, " ")
46 & " "
47 & ListGetAt(result.raw, 3, " "))>
48 <!--- Extract daylight savings time flag --->
49 <cfset result.dst=IIf(ListGetAt(result.raw, 4, " ") IS 0,
50 FALSE, TRUE)>
51 <!--- Extract leap month flag --->
52 <cfset result.leapmonth=IIf(ListGetAt(result.raw, 5, " ") IS 0,
53 FALSE, TRUE)>
54 <!--- Extract health flag --->
55 <cfset result.healthy=IIf(ListGetAt(result.raw, 6, " ") IS 0,
56 FALSE, TRUE)>
57 <!--- Extract advance milliseconds --->
58 <cfset result.msadv=ListGetAt(result.raw, 7, " ")>
59 <!--- Success --->
60 <cfset result.success=TRUE>
61
62 <!--- Catch any errors --->
63 <cfcatch type="any">
64 <cfset result.success=FALSE>
65 </cfcatch>
66
67 </cftry>
68
69 <cfreturn result>
70
71</cffunction>
2
3Name: GetNISTTime()
4
5Author: Ben Forta, 12/6/2005
6
7Description: Obtains current time data from NIST
8 Internet Time Service servers.
9
10 DST: US daylight savings time flag.
11 HEALTHY: TRUE if time server is healthy, FALSE if not.
12 JULIAN: Last 5 digits of Julian date/time value.
13 LEAPMONTH: TRUE is second will be added to or subtracted
14 from the current month.
15 MSADV: Number of milliseconds advanced by server to
16 compensate for network latency.
17 NOW: Current date/time.
18 RAW: Raw data from time server.
19 SUCCESS: TRUE if worked, FALSE if not, check
20 this flag first.
21
22Note: For a list of NIST time servers see:
23 http://tf.nist.gov/timefreq/service/time-servers.html
24 Servers should be addressed via IP address rather than
25 host name. The server used here is time.nist.gov
26 (192.43.244.18), but any of the listed servers will work.
27 To use an alternate server, just specify the IP
28 address in timeServer variable.
29--->
30
31<cffunction name="GetNISTTime" returntype="struct" output="false">
32 <cfset var timeServer="192.43.244.18">
33 <cfset var result=StructNew()>
34
35 <!--- Try/catch block --->
36 <cftry>
37
38 <!--- Try get time data --->
39 <cfhttp url="http://#timeServer#:13/" />
40 <!--- Save raw data --->
41 <cfset result.raw = CFHTTP.FileContent>
42 <!--- Extract Julian date --->
43 <cfset result.julian=ListGetAt(result.raw, 1, " ")>
44 <!--- Extract current date and time --->
45 <cfset result.now=ParseDateTime(ListGetAt(result.raw, 2, " ")
46 & " "
47 & ListGetAt(result.raw, 3, " "))>
48 <!--- Extract daylight savings time flag --->
49 <cfset result.dst=IIf(ListGetAt(result.raw, 4, " ") IS 0,
50 FALSE, TRUE)>
51 <!--- Extract leap month flag --->
52 <cfset result.leapmonth=IIf(ListGetAt(result.raw, 5, " ") IS 0,
53 FALSE, TRUE)>
54 <!--- Extract health flag --->
55 <cfset result.healthy=IIf(ListGetAt(result.raw, 6, " ") IS 0,
56 FALSE, TRUE)>
57 <!--- Extract advance milliseconds --->
58 <cfset result.msadv=ListGetAt(result.raw, 7, " ")>
59 <!--- Success --->
60 <cfset result.success=TRUE>
61
62 <!--- Catch any errors --->
63 <cfcatch type="any">
64 <cfset result.success=FALSE>
65 </cfcatch>
66
67 </cftry>
68
69 <cfreturn result>
70
71</cffunction>
To test this code you can just use:
1<cfset x=GetNISTTime()>
2<cfdump var="#x#">
2<cfdump var="#x#">