ZF-932: Proposed Feature: Enable Zend_Date / Zend_TimeSync to interoperate

Description

When I say "new Zend_Date()" with no parameters, I would like to have some way of instructing the ZF to give me a new Zend_Date object using time() + the offset from Zend_TimeSync. Thus, if someone gives me some code using Zend_Date, I have a way to make the existing code use the correct, "true" time for now.

Currently: $server = new Zend_TimeSync('ntp://serveraddress', 'alias'); $date = $server->getDate(); // pretend NTP server returned a time of 00:01 $date->isToday(); // fails if the actual server's time is 23:56 and the true time is 00:01

Proposed Change: $date->isToday() does not fail for the use case and situation above. For example, the protected _getTime() could be integrated in some way with Zend_TimeSync.

There are more situations like this, where Zend_Date relies on time(), which could be wrong.

Comments

I see some problems...

If we natively add Zend_Timesync with Zend_Date probably all users will use it because it returns the "exact" time which seems always to be better than the servers time in users view.

This way out Zend_Framework would spread all timeservers which could lead to massive negative image due to timeserver missuse.

Second: NTP and SNTP only define the time and the offset to actual time. We are not receiving day or date with the NTP packet.

Third: Implementing a "time-setter" function within Zend_Date could lead to missuse. A user could for example have the idea to add some "own" values to the existing date for example three hours because he has GMT+3

I'm not sure if we should implement such an problematic function.

The standard useage for Timesync is having an exact timestamp for database actions or other things which have to be very exact. The question is also if we should combine Timesync so close to Date and make it easy for the user to missuse it.

Having a returned Timesync Date is like having an own date defined. You have to use the proper functions which are not related to time()... there are only 3 functions which are related to time(). And all 3 can be used with Timesync but not the way you mentioned.

isToday() : $date->compareDate(Zend_Date::now());

is what you probably wanted to do. With this in mind it is not necessary to combine this two classes more as they are actualy.

1) The problem you mentioned is present even with Zend_TimeSync, by itself.

I am only proposing that we make it possible for ZF developers to solve the use case problem described above. I am not proposing that all uses of Zend_Date should be coupled to Zend_TimeSync and require Zend_TimeSync to first obtain a correct, accurate timestamp.

2) No day or date is needed from the NTP packet.. www.ntp.org/ntpfaq/NTP-s-def.htm" rel="nofollow">NTP uses UTC as reference time If we know the true time is "00:01", but the server's time is "23:56" we can calculate an offset and "fix" the server's time when using the function isToday() and thus solve the problem in the use case above.

3) I have not proposed a implementation of how to "set" the "now" time in Zend_Date, but only provided a use case which fails when the server's local time is wrong. Since we have Zend_TimeSync, there are multiple possible ways to solve the problem shown by this use case.

4) isToday() fails and produces the wrong answer in the situation above. If we provide no solution and a ZF developer is given some code written using the ZF, then the developer will have to debug and rewrite the code, instead of having a simple way to make existing uses of isToday() work on a sever with incorrect local, actual time.

5) If you strongly believe this use case should fail and give the wrong answer when the server's local time is not accurate, then I won't object if you close this issue. When the server's local time is wrong, there are other use cases that produce results developers do not expect, because many functions in Zend_Date and Zend_DateObject rely on either time() or _getTime().

I have to think a little more about this... I will give response tomorrow

Would a unit test for Zend_DateTest.php be helpful?


function testIsTodayWithTimeSync()
{
    $server = new Zend_TimeSync('ntp://serveraddress', 'alias');
    $date1 = $server->getDate();
    // need to use the proxy class to simulate time() returning wrong value
    $date2 = new Zend_Date_TestHelper($date1);

    // now simulate the server having an incorrect actual, local time:
    $date2->_setTime($date->getTimestamp() - 86400); // has side-effect

    // both Zend_Date objects have the same date/time/timestamp
    $this->assertSame($date1->getTimestamp(), $date2->getTimestamp());

    $this->assertTrue($date2->isToday()); // fails, but shouldn't because $date2 is today
}

I don't want to commit the code above, because the ideas in my email (leading to this Jira issue) for Zend_TimeSync were ideas and not absolute requirements but just brainstorming possible improvements for the i18n components. We could instead just document all the ways and places Zend_Date will fail when using Zend_Date objects created using Zend_TimeSync. I would need your help finding and documenting these places, since there are many other things I must also work on now.

I have a simpler solution in mind which I already know how to implement.

But anyway... a unit test would be nice.

Ok... I added the new feature.

Zend_TimeSync can now propose an offset to Zend_Date which will be used internally in all functions which make use of the time() function in Zend_Date.

The only thing which I need help with is a proper unit test... ( without changing the API :-) )

The issue itself was fixed with SVN 3567.