64-bit time_t

Discussion to talk about software related topics only.
Post Reply
SeeCwriter
Posts: 606
Joined: Mon May 12, 2008 10:55 am

64-bit time_t

Post by SeeCwriter »

I'm using v2.9.1 with a MOD5441X, and testing the new 64-bit time_t parameter with the function below.

Code: Select all

void TestDateTime( char *ptr )
{
   struct tm t, *timeinfo;
   char buf[20];

   iprintf( "Cmd: %s\r\n", ptr );
   memcpy( buf, ptr + 3,  4 );  buf[4] = 0;  t.tm_year = atoi( buf ) - 1900; 
   memcpy( buf, ptr + 8,  2 );  buf[2] = 0;  t.tm_mon  = atoi( buf ) - 1;
   memcpy( buf, ptr + 11, 2 );	buf[2] = 0;  t.tm_mday = atoi( buf );
   memcpy( buf, ptr + 14, 2 );	buf[2] = 0;  t.tm_hour = atoi( buf );
   memcpy( buf, ptr + 17, 2 );	buf[2] = 0;  t.tm_min  = atoi( buf );
   memcpy( buf, ptr + 20, 2 );	buf[2] = 0;  t.tm_sec  = atoi( buf );
   if ( t.tm_sec < 0 || t.tm_sec > 59 )      t.tm_sec  = 0;

   iprintf("Yr: %d, Mo: %d, Dy: %d, Hr: %d, Mi: %d, Se: %d\r\n", t.tm_year, 
                                                                 t.tm_mon,
                                                                 t.tm_mday, 
                                                                 t.tm_hour,
                                                                 t.tm_min,
                                                                 t.tm_sec  );
  time_t tnum = mktime( &t );
  iprintf( "Before time_t = %lld\r\n", tnum );

  set_time( tnum );                           // Set System time.

  tnum = 0;
  time( &tnum );
  iprintf( "After time_t = %lld\r\n", tnum );
  timeinfo = localtime( &tnum );
  iprintf( "Yr: %d, Mo: %d, Dy: %d, Hr: %d, Mi: %d, Se: %d\r\n", timeinfo->tm_year + 1900, 
                                                                 timeinfo->tm_mon + 1, 
                                                                 timeinfo->tm_mday, 
                                                                 timeinfo->tm_hour, 
                                                                 timeinfo->tm_min, 
                                                                 timeinfo->tm_sec  );
}
Output from function:

Code: Select all

Cmd: _A%2050/08/20,08:58
Yr: 150, Mo: 7, Dy: 20, Hr: 8, Mi: 58, Se: 0
Before time_t = -1750339816
After  time_t = -1750339816
Yr: 1914, Mo: 7, Dy: 15, Hr: 2, Mi: 29, Se: 44
Why is time_t a negative number, and why is the date and time way off?
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: 64-bit time_t

Post by pbreed »

It appears that mktime is broken.

If I set the time to 2037 it works.
It I set the time to 2037 and then
tnum+=0x40000000;

I get this result:
Yr: 2071, Mo: 8, Dy: 29, Hr: 22, Mi: 35, Se: 4

So the the lcoaltime and the time processing is all working, the mktime function is broken...

I'll see what I can do...
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: 64-bit time_t

Post by pbreed »

For now this hack seems to work...

time_t tnum = mktime( &t );
if((t.tm_year>137) && (tnum<0)) tnum+=0x100000000;
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: 64-bit time_t

Post by pbreed »

Fix for buggy mktime.

time_t tnum = mktime( &t );
if((t.tm_year>137) && (tnum<0)) tnum+=0x100000000;

If you implement the hack above:

The "Hack" will have no effect if the function mktime is correctly implemented in the future.
If mktime is NOT fixed the hack above will fail to work correctly in the early 2100's.
If mktime is fixed the hack won't effect that and the early 2100's will be just fine.

So while I'm calling it a hack to fix the current buggy mktime you are 100% safe to put that in your code, and if you forget to take it out at
a later date (when mktime is fixed) its still ok.

Paul
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: 64-bit time_t

Post by pbreed »

Specifically the hack will fail again in 2174
SeeCwriter
Posts: 606
Joined: Mon May 12, 2008 10:55 am

Re: 64-bit time_t

Post by SeeCwriter »

Thanks, that seems to have fixed the problem.

Out of curiosity, wouldn't it have been easier to make time_t an unsigned long (DWORD) rather than a signed 64-bit value?

Also, this too appears to fix the problem:

Code: Select all

time_t tnum = (DWORD) mktime(&t);
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: 64-bit time_t

Post by pbreed »

The new standard is 64 bit signed, so one can have dates before 1970.
Unsigned only works in one direction.
SeeCwriter
Posts: 606
Joined: Mon May 12, 2008 10:55 am

Re: 64-bit time_t

Post by SeeCwriter »

Ah! For the time travelers. I forgot about them.


Sorry. I couldn't help myself. :D
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: 64-bit time_t

Post by pbreed »

See time is not for just now, time is also used for dates and time in general, ie what was your birthday etc....

Some of us were born before 1970, so we need negative numbers....
Post Reply