Skip to Content.
Sympa Menu

freetds - Re: [freetds] dbdatecrack producing erroneous results

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Frediano Ziglio <freddy77 AT gmail.com>
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] dbdatecrack producing erroneous results
  • Date: Mon, 23 Apr 2012 17:45:36 +0100

I compared your function with tds_datecrack looping with a program
from 1753/1/1 to 4000/1/1 (not taking into account time) and I got
same results.

There should be something in the detection of msdblib flag that is wrong.

Frediano


Il 23 aprile 2012 03:07, crunsus <crunsus AT gmail.com> ha scritto:
> Absolutely, here is the code I am using to read datetime field from SQL
> Server 2008 R2
> This I found to produce wrong results with Visual Studio 2005 and
> linking statically with freetds 0.82
> I checked the newer releases but it looks like  tds_datecrack is still
> the same and didn't want to recompile the whole thing as the current
> version that I have matches what I have on the production server which
> is a CentOS with freetds 0.82 deployed and used by PHP as well, and it
> cannot be touched.
> So I do my development on Windows with VS2005 but deploy with a
> GCC/Makefile on Linux the same code as it is not Windows specific (just
> ANSI C++), on Windows being much easier to debug and that is why I
> prefer this method of working.
> Anyways this is the code that deals with reading and parsing datetime
> fields which doesn't work in all cases (on Windows):
>
>
> //this overloaded method for datetime types is currently not working
> well because
> //it uses dbdatecrack from dblib which appears to be broken in
> //FreeTDS (MS implementation of dblib works OK though, but don't want
> that dependency)
> void dbconn::get_data(int colid, DBDATEREC& val)
> {
>     DBINT dl;
>     char m[BUFSIZ];
>     int type;
>     BYTE *tmp;
>
>     if (colid < 0 || colid > dbnumcols(dbproc)) {
>         sprintf(m, "column %d: out of range", colid);
>         throw dbexception(m);
>     }
>
>     type = dbcoltype(dbproc, colid);
>     if ((type != SYBDATETIME )&&
>         type != SYBDATETIME4)){
>             sprintf(m, "column %d: datatype does not match", colid);
>             throw dbexception(m);
>     }
>
>     dl = dbdatlen(dbproc, colid);
>     if (dl) {
>         tmp = const_cast<BYTE*>(dbdata(dbproc, colid));
>         dbdatecrack(dbproc, &val, (DBDATETIME *)tmp);    // <------
> here is the problem !!!!!
>     } else memset(&val, 0, sizeof(DBDATEREC));
>
> }
>
> The temporary replacement for this above function that I had to come up
> with and which is absolutely ridiculous I know but it works 100%, is
> this monstrosity:
>
> //works very well for both datetime and smalldate types but is slow ,as
> opposed to dbcrackdate implementation from freeTDS which is fast but
> inaccurate
> void dbconn::get_data(int colid, DBDATEREC& val){
>     DBINT dl;
....




Archive powered by MHonArc 2.6.24.

Top of Page