[unixODBC-dev] possible bug in odbc++ library

Costin Iordache costin.iordache at scytl.com
Thu Nov 13 03:43:02 GMT 2008


Hi all,

 

I know that this is an unixODBC mail list and my question is related to
ODBC++ library but it was impossible to me to find a forum dedicated to
ODBC++ library. Sorry for any inconvenience.  I think Timestamp class has a
bug  and I'd be glad if somebody could confirm (or not) my supposition. Any
comment/suggestion is welcomed.

 

Next, I shortly describe the steps to reproduce the problem, the problem
description and the proposed fix:

 

Steps to reproduce:

 

1.       Create one DB (MY_DB)with one TIMESTAMP column  called "timecol"

2.       Set the computer TimeZone to "GMT+01:00 Madrid" with DST activated

3.       Write into the DB the timestamp "1225027900"; it corresponds to:

GMT timezone:    Sun, 26 Oct 2008 13:31:40 UTC

Madrid timezone: Sunday, October 26, 2008 2:31:40 PM

 

The following piece of code is used to save the timestamp:

..

std::time_t t = 1225027900;

odbc::PreparedStatement *ins_stmt(prepareStatement("insert into MY_DB
(\"timecol\") values (?)"));

ins_stmt->setTimestamp( 1, odbc::Timestamp(t));

ins_stmt->executeUpdate();

.

4.       Now, read from MY_DB:

 

.

odbc::PreparedStatement *sel_stmt(conn->get()->prepareStatement( "select *
from MY_DB" ) );

      odbc::ResultSet rset( sel_stmt->executeQuery() );

            

      odbc::Timestamp ts( rset->getTimestamp(1));

std::time_t loadedFromDB = ts.getTime();

.

 

5.       The value retrieved from DB of loadedFromDB should be 1225027900
but instead its value is 3600 seconds less, that is, 1225024300! 

 

Problem description:

 

Note: The 26th of October at 03:00 AM , Madrid's TS, is when the transition
from Daylight Saving Time (DST) to Standard Time (ST) takes place. 

 

.         When writing data to the DB the Timezone constructor calls
setTime(std::time_t) which in turn calls std::localtime. Thus, what we
actually get saved into the DB is a local time, i.e, in our particular case:
Sunday, October 26, 2008 2:31:40 PM which is correct taking into
consideration that Madrid's TZ is one hour ahead GMT.

.         When reading data back from the DB we first retrieve an object
"ts" which holds exactly the date from the DB, i.e., Sunday, October 26,
2008 2:31:40 PM. So far, so good. Now comes into play
odbc::Tiemstamp::getTime() method which is supposed to transform back the
local time kept inside "ts" object into UTC. Basically what it does is (for
the sake of simplicity I won't show all code details):

 

time_t Time::getTime() const

{

tm stm;

stm.tm_year=year_-1900;

stm.tm_mon=month_-1;

stm.tm_mday=day_;

stm.tm_hour=0;  //red row

stm.tm_min=0;   //red row

stm.tm_sec=0;   //red row

  stm.tm_isdst=-1; //negative means not known

 

  return std::mktime(&stm) + second_ + minute_*60 + hour_*3600; 

           }

 

                The problem we got here is easy to spot: std::mktime is
passed 00:00 AM (see the rows highlighted in red) that is, three hours
before the DST takes place. Therefore, std::mktime is unaware that the time
we actually want to compute is ST. If we passed day 27th instead of 26th ,
std::mktime would return the correct result because the hours, minutes and
seconds wouldn't matter to decide whether we have to deal with DST or ST! 

 

 

Proposed fix:

 


File

Code to be replaced

Replacement

Add


libodbc++-0.2.3\include\odbc++ \types.h

/** Gets the time_t value of this timestamp */

virtual std::time_t  Timestamp::getTime() {

return Date::getTime()+Time::getTime();

}

/** Gets the time_t value of this timestamp */

virtual std::time_t getTime();

-


libodbc++-0.2.3\src\ datetime.cpp

-

-

std::time_t Timestamp::getTime()

{

tm stm;

stm.tm_year=year_-1900;

stm.tm_mon=month_-1;

stm.tm_mday=day_;

stm.tm_hour=hour_;

stm.tm_min=minute_;

stm.tm_sec=second_;

stm.tm_isdst=-1; //negative means not known

return mktime(&stm);

}

 

 

Thanks for any help/suggestion,

Costin.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.unixodbc.org/pipermail/unixodbc-dev/attachments/20081113/3188268c/attachment-0001.html>


More information about the unixODBC-dev mailing list