The 4.1.2 (and before) mssql entension returns datetime fields as a locale specific format eg: Oct 30 2001 7:44PM, which doesn't allow access to the seconds or milliseconds field of datetime. I patched my copy of mssql to have a php.ini entry mssql.longdatetime which tells mssql to return datetime in the long format: eg: 2001-10-30 19:44:54.206. 99% of the changes are in php_mssql.c with php_mssql.h just needing a variable added to it. Diff of php4.1.2 php_mssql.c => my patch ver
45,46c45,46
< static void php_mssql_get_column_content_with_type(mssql_link *mssql_ptr,int offset,zval *result, int column_type);
< static void php_mssql_get_column_content_without_type(mssql_link *mssql_ptr,int offset,zval *result, int column_type);
---
> static void php_mssql_get_column_content_with_type(mssql_link *mssql_ptr,int offset,zval *result, int column_type,long longdatetime);
> static void php_mssql_get_column_content_without_type(mssql_link *mssql_ptr,int offset,zval *result, int column_type,long longdatetime);
136a137
> STD_PHP_INI_BOOLEAN("mssql.longdatetime", "0", PHP_INI_ALL, OnUpdateBool, longdatetime, zend_mssql_globals, mssql_globals)
739c740
< static void php_mssql_get_column_content_with_type(mssql_link *mssql_ptr,int offset,zval *result, int column_type)
---
> static void php_mssql_get_column_content_with_type(mssql_link *mssql_ptr,int offset,zval *result, int column_type,long longdatetime)
795,801c796,823
< char *res_buf;
< int res_length = dbdatlen(mssql_ptr->link,offset);
< if (column_type == SQLDATETIM4) res_length += 14;
< if (column_type == SQLDATETIME) res_length += 10;
<
< res_buf = (char *) emalloc(res_length + 1);
< res_length = dbconvert(NULL,column_type,dbdata(mssql_ptr->link,offset), res_length,SQLCHAR,res_buf,-1);
---
> char *res_buf; > int res_length;
>
> if (column_type == SQLDATETIME && longdatetime ) {
> /* if it is the long date time format and user wants the extended date/time (with seconds and millis)*/
> /* then output: 2001-03-15 23:06:36.000 */
> DBDATEREC dr;
>
> if (dbdatecrack(mssql_ptr->link,&dr,(DBDATETIME *)dbdata(mssql_ptr->link,offset)) != SUCCEED) {
> php_error(E_ERROR,"MS SQL: column %d unable to convert datetime field", offset);
> ZVAL_FALSE(result);
> /* no further processing */
> return;
> }
>
> res_length = 23;
> res_buf = (char *) emalloc(res_length+1);
> sprintf(res_buf,"%4d-%02d-%02d %02d:%02d:%02d.%03d",
> dr.year,dr.month,dr.day,dr.hour,dr.minute,dr.second,dr.millisecond);
>
> } else {
> res_length = dbdatlen(mssql_ptr->link,offset);
> if (column_type == SQLDATETIM4) res_length += 14;
> if (column_type == SQLDATETIME) res_length += 10;
>
> res_buf = (char *) emalloc(res_length + 1);
> res_length = dbconvert(NULL,column_type,dbdata(mssql_ptr->link,offset), res_length,SQLCHAR,res_buf,-1);
> }
814c836
< static void php_mssql_get_column_content_without_type(mssql_link *mssql_ptr,int offset,zval *result, int column_type)
---
> static void php_mssql_get_column_content_without_type(mssql_link *mssql_ptr,int offset,zval *result, int column_type, long unused)
858a881,885
> /* Ugh.. It would be cleaner to fetch the longdatetime in */
> /* get_column_content_with_type, but doing the thread-safe lookup */
> /* for every row that has a datetime field seems bad also. So get it */
> /* here and pass the value in */
> long longdatetime = MS_SQL_G(longdatetime);
916c943
< MS_SQL_G(get_column_content(mssql_ptr, j+1, &result->data[i][j], column_types[j]));
---
> MS_SQL_G(get_column_content(mssql_ptr, j+1, &result->data[i][j], column_types[j],longdatetime));