Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_TimeSync Component Proposal

Proposed Component Name Zend_TimeSync
Developer Notes
Revision 5.0 - 2 December 2007: Finished implementation
4.0 - 28 November 2006: Reworked proposal based on actual work and feedback from Zend
3.0 - 06 November 2006: Reworked proposal based on feedback from various people
2.0 - 06 November 2006: Reworked proposal based on actual work
1.0 - 11 October 2006: Proposal submitted (wiki revision: 25)

Table of Contents

1. Overview

Zend_TimeSync implements the ability for TimeSyncronisation to the Framework.

Note that best practices would rely on a local service to sync the local clock to remote NTP servers, so that microtime() would simply return precisely accurate results. However, sometimes a developer must use a server lacking this kind of local service.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • Zend_TimeSync needs Zend_Date to handle timestamps properly
  • Zend_TimeSync can not change the server's time
  • Zend_TimeSync will use an internal caching mechanism (Zend_Cache) to prevent overload

4. Dependencies on Other Framework Components

  • Zend
  • Zend_Date
  • Zend_Cache
  • Zend_Exception

5. Theory of Operation

This component is able to receive internet or network time from a timeserver using the NTP or SNTP protocol. By using this component a page/script is able to act indepentendly from the timesettings of the server the script is running. However, in practical terms, this component uses internaly a caching mechanism (Zend_Cache) to prevent overload.

Zend_TimeSync will allow multiple servers to be added to the class constructor as an array. These servers would then be used as "fallback" servers. The class will automaticly switch to the next timeserver - which can be a mix of ntp and sntp timeservers - on port/server error.

This class is not able to change the server's time but it will return a date object from which the difference to the servers time can be worked with.

6. Milestones / Tasks

  • Milestone 1: [DONE] proposal written
  • Milestone 2: [DONE] implementing Ntp
  • Milestone 3: [DONE] implementing Sntp
  • Milestone 4: [DONE] Unit tests and debugging
  • Milestone 5: [DONE] Documentation

7. Class Index

  • Zend_TimeSync
  • Zend_TimeSync_Protocol
  • Zend_TimeSync_Ntp
  • Zend_TimeSync_Sntp
  • Zend_TimeSync_Exception

8. Use Cases

Getting actual time from a NTP server with a standard port:

Getting actual time from a SNTP server with standard port:

Getting actual time from an NTP server with standard port, and a list of NTP fallback servers provided (remember, first in == first out)

Getting actual time from a SNTP server with standard port, and a list of SNTP fallback servers provided (remember, first in == first out)

Getting actual time from an NTP server with a none standard port, and with a list of NTP fallback servers, which also run on a none standard port (remember, first in == first out)

Getting actual time from an SNTP server with a none standard port, and with a list of SNTP fallback servers, which also run on a none standard port (remember, first in == first out)

Getting actual time from an NTP server with a standard port, and with a list of SNTP fallback servers running on a none standard port(remember, first in == first out)

taking care of errors/exceptions:

9. Class Skeletons

Zend_Timesync returnes a Zend_Date object which represents the time from the (S)NTP Server



Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Oct 11, 2006

    <p>I don't like the idea of passing a constant to the constructor specifying the protocol; this is a non-standard approach. It is more intuitive (and actually less typing) to instantiate the subclass directly. The <code>Zend_TimeSync_Abstract</code> class is not needed. Instead, make <code>Zend_TimeSync</code> itself an <code>abstract</code> class:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    abstract class Zend_TimeSync

    class Zend_TimeSync_Ntp extends Zend_TimeSync {}

    <p>The use case then becomes:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    $server = new Zend_TimeSync_Ntp('');
    $date = $server->getTime();

    <p>The public API is inherited from the base <code>Zend_TimeSync</code> class while all of the protocol-specific functionality is contained within overridden <code>protected</code> methods in the protocol-specific subclass.</p>

    <p>Also, the framework naming convention for class names requires that acronyms be lower-case with an initial capital: <code>Zend_Pdf</code>, <code>Zend_Http_Client</code>, et al. (<a href="">reference</a>). The NTP and SNTP subclasses must then be named <code>Zend_TimeSync_Ntp</code> and <code>Zend_TimeSync_Sntp</code> respectively.</p>

    1. Oct 11, 2006

      <p>Unofficial comments and thoughts ...</p>

      <p>Since all the plugins can share a common superclass <code>Zend_TimeSync</code>, I agree with Willie. However, these changes then create a need for a factory method to create the appropriate instance given input of a string: 'NTP', 'SNTP', or 'SWATCH'.</p>

      <blockquote><p>The NTP and SNTP subclasses must then be named <code>Zend_TimeSync_Ntp</code> and <code>Zend_TimeSync_Sntp</code> respectively.</p></blockquote>

      <p>These naming conventions led to the changes in Zend_Db's factory() method, supporting instantiation of plugins identified from strings following a convention like 'PDO_MYSQL'. We need to all use a common ZF standard for working with factories and plugins. I will resume again the public discussion of factory and plugin conventions, as nobody has yet found a solution that meets all our goals: <a class="external-link" href=""></a></p>

      1. Oct 11, 2006

        <p>However, these changes then create a need for a factory method...</p></blockquote>

        <p>While I agree that object factories can be useful, they aren't necessary in every case, and I can't see why one should be needed here. Factories are most beneficial when: they can conserve resources by reusing shared instances; they save lines and lines of code by instantiating difficult (or very common) objects; or the desired subclass cannot be easily ascertained. None of those applies here.</p>

        <p> create the appropriate instance given input of a string: 'NTP', 'SNTP', or 'SWATCH'.</p></blockquote>

        <p>You've only suggested that the parameter which would have used a class constant be replaced with a string. If a factory is truly necessary, I'd prefer to use constants.</p>

    2. Oct 12, 2006

      <p>As this makes sense in my eyes I changes the proposal as expected.</p>

  2. Oct 11, 2006

    <p>Although i <em>may</em> just be misunderstanding the proposal, this seems like a REALLY niche issue.<br />
    Seems kinda wierd you would be on a system where you can't even trust what DAY the server is telling you it is, and furthermore with </p>
    <ac:macro ac:name="code"><ac:parameter ac:name="type">php</ac:parameter><ac:plain-text-body><![CDATA[
    $server = new Zend_TimeSync(Zend_TimeSync::SWATCH, '', 2000);
    $date = $server->getTime();


    <p>would this functionality make up for netlag and the (micros)time between calls?</p>

    <p>I could understand a component to deal with like an application specific now() wrapper to make up for a GMT offset or the like, but i think its a system issue if your system clock is off.</p>

    <p>my $0.02</p>

    1. Oct 11, 2006

      <p>More unofficial comments ...</p>

      <p>I do not often see a need for this in my experiences, but I did need something similar recently. In order for this proposal to meet the need I had recently, the proposal would need to be extended to support using Zend_Cache to cache the difference between the server's time and real time, in microseconds.</p>

      <p>In some circumstances, people must deploy PHP applications on server clusters, and the times might not be reliable due to software issues, hardware issues, or system administration troubles. When the PHP applications write information into a shared database, the timestamp must be kept consistent. Using a combination of Zend_Cache and Zend_TimeSync could yield an efficient solution to this niche problem. I'm less clear about how Swatch time is relevent or better than using GMT/UTC for ZF applications.</p>

      1. Oct 12, 2006

        <p>I dont see the problem here...</p>

        <p>Zend_TimeSync_xxx returns you always a Zend_Date object.<br />
        So you can always do a</p>

        <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
        $mydate = new Zend_Date();

        $serverdate = new Zend_TimeSync_Ntp('');
        $difference = $serverdate->subTimestamp($mydate);

        echo $difference;

        <p>The Swatch protocol itself was only included by me because I always want "complete" solutions...<br />
        I know that it's not supporting a real UTC, but I think sometimes it could be nice to include a actual SWATCH-TIME into a homepage.</p>

        <p>So Swatch is only for homepage playing and not for big PHP applications.</p>

  3. Oct 11, 2006

    <p>Something I forgot to mention in my original comment...</p>

    <p>NTP and SNTP are based on UDP, not TCP (and by extension HTTP). From Section 4 of <a href="">RFC 4330</a>:</p>

    <p>4. Message Format</p>

    <p> Both NTP and SNTP are clients of the User Datagram Protocol (UDP)</p></blockquote>

    <p>The example provided in the use case then is incorrect. You cannot specify an HTTP or similar URI to contact an NTP or SNTP server. You can only accept a host name or IPv4 or IPv6 address:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    $server = new Zend_TimeSync_Ntp(''); // or
    $server = new Zend_TimeSync_Ntp(''); // or
    $server = new Zend_TimeSync_Ntp('2001:0db8:0:0:0:0:1428:57ab');

    1. Oct 12, 2006

      <p>I knew this... a was just so in hurry-writing that I didnt recognise my fault <ac:emoticon ac:name="wink" /></p>

      <p>This is already corrected.</p>

  4. Nov 07, 2006

    <p>Proposal has been updated to get in line with all the feedback that has been received.</p>

    1. Nov 08, 2006

      <p>Implemented are now several changes which have been discussed with several other Frameworkers.<br />
      We've already coded the SNTP and NTP stack which works really nice and fast. <ac:emoticon ac:name="smile" /></p>

      <p>Now we're waiting for the approvement from Zend so we can commit our code to the incubator. Hopefully this will be within the next few days.</p>

  5. Nov 13, 2006

    <ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Feedback</ac:parameter><ac:rich-text-body>
    <p>This proposal has been accepted as part of the ZF core "Locale" project, provided:</p>
    <li>an additional use case is added (and supported) showing the use of exceptions to handle error conditions, and</li>
    <li>an additional use case (psuedo code is ok), showing a situation that justifies the existence of this class in the ZF core. A short explanation of the example should also be added to the Overview of the proposal, to help readers understand why a developer might <strong>need</strong> to use this class. For example, if the developer does not have the ability to fix the clock or date on the server, but needs to store some data to a local SQLite DB with an accurate date timestamp, how would a developer use this class on a busy website to accomplish this goal, without risking a time server banning/blocking the developer's server?</li>

  6. Nov 28, 2006

    <p>added use case (and support) for showing the use of exceptions and updated class skeletons</p>