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:































To test this code you can just use:

14 thoughts

  1. Or if you can add .jar file to CF server /lib directory, then you can use some free SNTP lib like this one:
    http://alpha.uhasselt.be/Research/Algebra/Members/Java/java.html
    And then use code like this:
    <cfscript>
    ntpServer = "time.nist.gov";
    ntpConn = CreateObject("java", "be.ac.luc.vdbergh.ntp.NtpConnection");
    ntpConn.init(CreateObject("java", "java.net.InetAddress").getByName(ntpServer));
    time = ntpConn.getTime();
    </cfscript>
    <cfoutput>#time#</cfoutput>

  2. Nice one. We just implemented something similar in my company. We’re starting to have overseas clients (as opposed to aussie only before), so we needed to save absolute times in the DB yet display relative times to our customers. For example, if I buy something on an american website, I need to see the aussie purchase-date/time on my screen, and my customer rep needs to see the american one. In our case (e-recruitment) it’s even more crucial, as we schedule interviews, invite candidates to tests and so on…
    It’s actually much trickier than it seems , mostly because of daylight savings. DS is chosen by governments and can change any year. It doesn’t have to be a full hour, and it doesn’t even have to be there at all.
    Here in Oz, we have DS in victoria (melbourne), but not in Tasmania (the island). My point is, there is absolutely no way to calculate it, so you have to get the info somewhere. you could use a timeserver, but :
    1.what if it goes down?
    2.different business objects in our system can belong to different timezones, so we can’t just save a time-offset once and for all in the session.
    So what we did (not me but a guy here) was instanciate the java.util.TimeZone class that’s shipped with JRun and contains all that info (updated everytime they update jrun I think). add a whole lot of small udfs to calculate offsets to the recipe, and that’s a wrap. We did have a few load problems, apparently because we’re still running on CF5 šŸ™ which doesn’t handle java as well as MX, but now it seems to be fine.
    Any comment on this solution would be more than welcome. don’t hesitate to tell me if I’m plain wrong about something because I’m a junior developer, and I didnt work on that project so I may be mistaken on some points.

  3. hey, thanks for that, it looks cool. We’re actually going to re-design the application next year, using cf7 and machii (maybe flex2). And we’re talking about a 300 000-lines app that has grown for 7 years. Can’t wait to add OO and framework skills to my quiver!

  4. Errr…
    What is the purpose of this:
    <cfset result.leapmonth=IIf(ListGetAt(result.raw, 5, " ") IS 0,FALSE, TRUE)>
    Wouldn’t
    <cfset result.leapmonth=ListGetAt(result.raw, 5, " ") NEQ 0>
    Do the same without the added overhead of Iif()?

  5. Looks like result.now gives an incorrect date, the day and year get swapped. A simple fix is to change ParseDateTime to LSParseDateTime:
    &lt;!— Extract current date and time —&gt;
    <br >
    &lt;cfset result.now=LSParseDateTime(ListGetAt(result.raw, 2, &quot; &quot;)
    &amp; &quot; &quot;
    &amp; ListGetAt(result.raw, 3, &quot; &quot;))&gt;

  6. @Al Everett:
    I was about to post pretty much the exact same message as you.. that is until I saw your message šŸ™‚ And I’m still curious to hear the answer of course šŸ™‚

  7. Al, Auke, no reason, just kinda happened. šŸ™‚ I had cfif statements while testing, and then turned it into an IIf(). But what you suggested will work just as well, maybe better.

  8. Aight, just checking šŸ™‚
    Btw: looking at the timestamps of these postings, it looks like your server could use some time synchronization šŸ˜€

  9. Didn’t IIF used to be significantly slower than <cfif>? Is that no longer the case?
    In any event, I prefer not to use IIF for two reasons:
    1. <cfif> tags are more readable
    2. All three of the parts of an IIF need to be valid at run-time or it will throw an error, while <cfif> doesn’t. For instance, this will bomb out: <cfset foo=iif(isDefined("variables.bar"),variables.bar,de("Not defined"))> if variables.bar is not defined, while this will not:
    <cfif isDefined("variables.bar")>
    <cfset foo=variables.bar>
    <cfelse>
    <cfset foo="Not defined">
    </cfif>

  10. It has it’s uses (IMHO).

    <select name="selectBox">
    <cfloop query="qQuery">
    <option
    value="#nID#
    #iif( nID eq url.nParam, de( ‘selected="selected"’ ), de( ” ))#
    >#sName#</option>
    </cfloop>
    </select>

Leave a Reply