ID:               28543
 Updated by:       [EMAIL PROTECTED]
 Reported By:      rjones-php-ibase-bug at ico dot viva dot org
 Status:           Bogus
 Bug Type:         InterBase related
 Operating System: windows 2000 and Linux
 PHP Version:      4.3.6
 New Comment:

First of all, my apologies if I offended you in any way. I didn't mean
to be rude, but your patch was really bad.

Anyway:
the Interbase driver uses 'struct tm' internally, which is basically a
non-textual representation of a timestamp [Try 'man mktime' in a Unix
shell for more info] The conversion to a printable format is carried
out by strftime(), which is a C library call, and _not_ a PHP
[internal] function.
 
Apparently, the different C libraries don't agree on the way years <
1000 should be printed [for the %Y conversion]. Some print leading
zeroes, some don't. There's really nothing we can do about that. The
only possibility you have is changing the format string which is being
fed to strftime() [by using ibase_timefmt()] and replace %Y with %C%y,
which will print the year 1 as 001 [not 0001]. However, %C is not
supported by Win32 (as far as I can tell by looking at MSDN)

Currently, the [badly chosen] default timestamp format is not
compatible with literal timestamps in SQL, as you pointed out. This
format is just the default, so you can change that yourself. The
built-in default will not be changed before the release of PHP 5, as
doing so might break backward compatibility for some users.

Finally, there's no point in maintaining this report as a feature
request, as the real underlying problem is in strftime() [if you can
even call it a problem: POSIX does not dictate whether %Y should print
leading zeroes or not]





Previous Comments:
------------------------------------------------------------------------

[2004-05-28 16:12:21] rjones-php-ibase-bug at ico dot viva dot org

My "patch" sucks, I freely admit it; except that it's not a patch. It's
a workaround that I used to get things working in my situation, and not
intended to be a general fix.  My colleague, who is more familiar with
C than I am pointed out that it would be better to use %04d. Maybe
there's other stuff wrong with it. That is independent of whether there
is a problem or not.

I'm sorry I didn't make it clearer, but there was no need to be rude
like that. I'll try to explain the problem further. 

I haven't tested this thoroughly, but it seems that the way years are
displayed by interbase is with leading zeros making the number of
digits exactly four. This is true in isql, ibconsole and all other
programs I've used with it.  It doesn't seem sensible to me that php's
interbase driver doesn't do the same, particularly as passing the
string back in a query causes the query to fail.

If you would like me to find out more about this, I can in time. I
would appreciate a more constructive approach to the problem, though I
realise there are a lot of time-wasters about.

I hope you will reconsider this, and if you cannot bring yourself to
describe it as a valid bug, at least let it stand as a feature request.
If I have thoroughly misunderstood the problem, perhaps you can direct
me towards enlightenment.

------------------------------------------------------------------------

[2004-05-28 01:05:57] [EMAIL PROTECTED]

Apparently, the Windows and GNU implementations of strftime() behave
differently. Nothing we can do about that. You can use ibase_timefmt()
to change the way strftime() is applied.

BTW, your patch sucks. You're using tm_year, which holds the number of
years since 1900, and comparing it < 10, causing '1900' to be printed
as '0001900'. Please don't post untested crap here.

------------------------------------------------------------------------

[2004-05-27 16:54:47] rjones-php-ibase-bug at ico dot viva dot org

Description:
------------
This function does not work consistently on Linux and Windows 2000 with
dates with small years.

The strings it returns are
under Linux: "01/01/1"
under Windows: "01/01/0001"

I have traced this back:
        ibase_fetch_row -> _php_ibase_fetch_hash -> _php_ibase_var_zval ->
strftime

in interbase.c at line 1919:

#if HAVE_STRFTIME
                                Z_STRLEN_P(val) = strftime(string_data, 
sizeof(string_data),
format, &t);
#else
                                /* FIXME */
                                if (!t.tm_hour && !t.tm_min && !t.tm_sec) {
                                        Z_STRLEN_P(val) = sprintf(string_data, 
"%02d/%02d/%4d", t.tm_mon +
1, t.tm_mday, t.tm_year + 1900);
                                } else {
                                        Z_STRLEN_P(val) = sprintf(string_data, 
"%02d/%02d/%4d
%02d:%02d:%02d", t.tm_mon+1, t.tm_mday, t.tm_year + 1900, t.tm_hour,
t.tm_min, t.tm_sec);
                                }
#endif

As a work-around, I've used 

#if HAVE_STRFTIME
// Make this consistent with PHP on windows.
// FixMe This should give consistent results for all years from 0001
onwards
                                if(t.tm_year < 10)      
                                {
                                        if (!t.tm_hour && !t.tm_min && !t.tm_sec) {
                                                Z_STRLEN_P(val) = sprintf(string_data, 
"%02d/%02d/000%d",
t.tm_mon + 1, t.tm_mday, t.tm_year+1900);
                                        } else {
                                                Z_STRLEN_P(val) = sprintf(string_data, 
"%02d/%02d/000%d
%02d:%02d:%02d", t.tm_mon+1, t.tm_mday, t.tm_year+1900, t.tm_hour,
t.tm_min, t.tm_sec);
                                        }
                                }
                                else
                                {
                                        Z_STRLEN_P(val) = strftime(string_data, 
sizeof(string_data),
format, &t);
                                }
#else
                                /* FIXME */
                                if (!t.tm_hour && !t.tm_min && !t.tm_sec) {
                                        Z_STRLEN_P(val) = sprintf(string_data, 
"%02d/%02d/%4d", t.tm_mon +
1, t.tm_mday, t.tm_year + 1900);
                                } else {
                                        Z_STRLEN_P(val) = sprintf(string_data, 
"%02d/%02d/%4d
%02d:%02d:%02d", t.tm_mon+1, t.tm_mday, t.tm_year + 1900, t.tm_hour,
t.tm_min, t.tm_sec);
                                }
#endif


Reproduce code:
---------------
$rs_temp=ibase_query("SELECT time_stamp_field FROM
some_stored_procedure()"); 
$row_temp=ibase_fetch_row($rs_temp);
print($row_temp[0]); 

Expected result:
----------------
01/01/0001

Actual result:
--------------
01/01/1


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=28543&edit=1

Reply via email to