Skip navigation.
Home
The QNX Community Portal

View topic - QNX4 works beyond 2038: is it a bug?

QNX4 works beyond 2038: is it a bug?

Read-only archive of qnx.qnx4 (General QNX4 Discussion Group) at inn.qnx.com

QNX4 works beyond 2038: is it a bug?

Postby booBot » Wed Aug 16, 2006 12:57 am

I stumbled upon an unexpected behaviour of QNX v4.25G (Proc32 v4.25Q) - it
seemingly continues to handle the time properly at least for some more
days past 19/01/2038.
Here is an example:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <tzfile.h>

#define NEED_MJD 1

#ifdef NEED_MJD
# define JULIAN_OFFSET (1721059 - 2400000) /* use MJD */
#else
# define JULIAN_OFFSET 1721059 /* full Julian Days */
#endif

typedef unsigned long jday;

jday
Tm2Julian( struct tm *Tm )
{
jday JulDay;
int Year; /* full four-digit year */
int Year1; /* Year, less 1 */

Year = Tm->tm_year + TM_YEAR_BASE;
Year1 = Year - 1; /* year, less 1 */
JulDay = Year * 365; /* approx days */
JulDay += (Year+3) / 4; /* leap years */
JulDay -= Year1 / 100; /* fix for 100 */
JulDay += Year1 / 400; /* fix for 400 */
JulDay += Tm->tm_yday; /* ordinal day */
JulDay += JULIAN_OFFSET; /* fix */

return JulDay;
}

time_t
mjd2unixtime( unsigned long jday )
{
time_t unixtime;

// if( 40587 <= jday & jday <= 90297 ) /* apparently works */
if( 40587 <= jday & jday <= 65442 ) /* garateed to work */
{
unixtime = ( jday - 40587 ) * 60*60*24;
return( unixtime);
}
return -1; /* there is no time_t representation for dates */
} /* before 01/01/1970 and after 19/01/2038 */

void
main( void )
{
jday jd;
time_t t_o_d;
char buf[26];
struct tm tmbuf;

jd = 40586; /* 31/12/1969 */
t_o_d = mjd2unixtime( jd );
_gmtime( &t_o_d, &tmbuf );
printf( "MJD(%d)==%.24s GMT, time_t==0x%lx\n", jd, _asctime( &tmbuf, buf
), t_o_d );
jd = 40587; /* 01/01/1970 */
t_o_d = mjd2unixtime( jd );
_gmtime( &t_o_d, &tmbuf );
printf( "MJD(%d)==%.24s GMT, time_t==0x%lx\n", jd, _asctime( &tmbuf, buf
), t_o_d );
jd = 45000; /* 31/01/1982 */
t_o_d = mjd2unixtime( jd );
_gmtime( &t_o_d, &tmbuf );
printf( "MJD(%d)==%.24s GMT, time_t==0x%lx\n", jd, _asctime( &tmbuf, buf
), t_o_d );
jd = 53005; /* 01/01/2004 */
t_o_d = mjd2unixtime( jd );
_gmtime( &t_o_d, &tmbuf );
printf( "MJD(%d)==%.24s GMT, time_t==0x%lx\n", jd, _asctime( &tmbuf, buf
), t_o_d );
jd = 53963; /* 16/08/2006 */
t_o_d = mjd2unixtime( jd );
_gmtime( &t_o_d, &tmbuf );
printf( "MJD(%d)==%.24s GMT, time_t==0x%lx)\n", jd, _asctime( &tmbuf, buf
), t_o_d );
jd = 65442; /* 19/01/2038 */
t_o_d = mjd2unixtime( jd );
_gmtime( &t_o_d, &tmbuf );
printf( "MJD(%d)==%.24s GMT, time_t==0x%lx\n", jd, _asctime( &tmbuf, buf
), t_o_d );
jd = 65443; /* 20/01/2038 */
t_o_d = mjd2unixtime( jd );
_gmtime( &t_o_d, &tmbuf );
printf( "MJD(%d)==%.24s GMT, time_t==0x%lx\n", jd, _asctime( &tmbuf, buf
), t_o_d );
jd = 90296; /* 06/02/2106 */
t_o_d = mjd2unixtime( jd );
_gmtime( &t_o_d, &tmbuf );
printf( "MJD(%d)==%.24s GMT, time_t==0x%lx\n", jd, _asctime( &tmbuf, buf
), t_o_d );
jd = 90297; /* 07/02/2106 */
t_o_d = mjd2unixtime( jd );
_gmtime( &t_o_d, &tmbuf );
printf( "MJD(%d)==%.24s GMT, time_t==0x%lx\n", jd, _asctime( &tmbuf, buf
), t_o_d );
}

Somewhere closer to 2106 the date starts to be off by one day - instead of
07/02/2106 it shows 06/02/2106.

Please comment!

Tony.
booBot
Senior Member
 
Posts: 633
Joined: Tue Feb 24, 2004 5:07 pm

Re: QNX4 works beyond 2038: is it a bug?

Postby booBot » Wed Aug 16, 2006 12:57 pm

On Wed, 16 Aug 2006 04:57:17 +0400, Tony <mts.spb.suxx@mail.ru> wrote:
Somewhere closer to 2106 the date starts to be off by one day - instead
of 07/02/2106 it shows 06/02/2106.
I poked around and it seems that both MJD 88585 and MJD 88586 in current

"gmtime()" maps to the same "01JUN2101". From that day on "gmtime()" is
off by a day.
Untill that date everything seems to work correctly.

Please comment.

Tony.

PS
Is it posible to obtain the sources for "gmtime()" to fix and replace in
Watcom's libraryes?
(Watcom C v10.6B+Security patch)
booBot
Senior Member
 
Posts: 633
Joined: Tue Feb 24, 2004 5:07 pm

Re: QNX4 works beyond 2038: is it a bug?

Postby booBot » Wed Aug 16, 2006 2:57 pm

I wonder how is this possible?

The <time.h> file declares the "time_t" as the "signed long"...

Tony.
booBot
Senior Member
 
Posts: 633
Joined: Tue Feb 24, 2004 5:07 pm

Re: QNX4 works beyond 2038: is it a bug?

Postby booBot » Wed Aug 16, 2006 3:22 pm

On Wed, 16 Aug 2006 16:57:43 +0400, Tony <mts.spb.suxx@mail.ru> wrote:
I poked around and it seems that both MJD 88585 and MJD 88586 in current
"gmtime()" maps to the same "01JUN2101". From that day on "gmtime()" is
off by a day.
Interestingly, the week-day increases correctly:

MJD(88585)==Wed Jun 01 00:00:00 2101 GMT, time_t==0xf72e9d00
MJD(88586)==Thu Jun 01 00:00:00 2101 GMT, time_t==0xf72fee80

Week-day calculation seems correct right to the time_t=0xffffffff (MJD
90297, Sun Feb 07 2106), it is "day of month" that gets botched...

Tony.
booBot
Senior Member
 
Posts: 633
Joined: Tue Feb 24, 2004 5:07 pm

Re: QNX4 works beyond 2038: is it a bug?

Postby Wojtek Lerch » Wed Aug 16, 2006 4:08 pm

Tony wrote:
I wonder how is this possible?

By using an unsigned type internally?

The <time.h> file declares the "time_t" as the "signed long"...

Since POSIX specifically says that negative time_t values are undefined,
we're free to map them to dates after 2038. It's not a bug, it's a
feature. ;)

http://www.opengroup.org/onlinepubs/009 ... #tag_04_14
Wojtek Lerch
 

Re: QNX4 works beyond 2038: is it a bug?

Postby booBot » Wed Aug 16, 2006 8:47 pm

On Wed, 16 Aug 2006 20:08:55 +0400, Wojtek Lerch <Wojtek_L@yahoo.ca> wrote:
It's not a bug, it's a feature.
I do remember the warning in the Documentation - "If you need to use QNX4

after 2038 - ask for individual support plan" - or something like that.

I did not try setting the system time that far yet. I do not know if I'll
be able to recover an installation if something goes "Oops!"... May be not
only the "/bin/date" faults but something in the "/bin/Fsys" or "Proc32"
too. Scary!

I'll try this in VMwared installation first.

Tony.
booBot
Senior Member
 
Posts: 633
Joined: Tue Feb 24, 2004 5:07 pm

Re: QNX4 works beyond 2038: is it a bug?

Postby booBot » Wed Aug 16, 2006 8:48 pm

On Wed, 16 Aug 2006 19:22:30 +0400, Tony <mts.spb.suxx@mail.ru> wrote:
I poked around and it seems that both MJD 88585 and MJD 88586 in
current "gmtime()" maps to the same "01JUN2101". From that day on
"gmtime()" is off by a day.
Interestingly, the week-day increases correctly:
MJD(88585)==Wed Jun 01 00:00:00 2101 GMT, time_t==0xf72e9d00
MJD(88586)==Thu Jun 01 00:00:00 2101 GMT, time_t==0xf72fee80

Week-day calculation seems correct right to the time_t=0xffffffff (MJD
90297, Sun Feb 07 2106), it is "day of month" that gets botched...
This "_gmtime()" does not have this defect and I believe it works

correctly all over the range of "*timer" values - from 0x0 up to
0xffffffff.

#include <time.h>

#define YEAR0 1900
#define EPOCH_YR 1970
#define SECS_DAY (24L * 60L * 60L)
#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) ||
!((year) % 400)))
#define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)

const int _ytab[2][12] {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

struct tm
*_gmtime(const time_t *timer, struct tm *tmbuf)
{
time_t time = *timer;
unsigned long dayclock, dayno;
int year = EPOCH_YR;

dayclock = (unsigned long) time % SECS_DAY;
dayno = (unsigned long) time / SECS_DAY;

tmbuf->tm_sec = dayclock % 60;
tmbuf->tm_min = (dayclock % 3600) / 60;
tmbuf->tm_hour = dayclock / 3600;
tmbuf->tm_wday = (dayno + 4) % 7; // Day 0 was a thursday
while (dayno >= (unsigned long) YEARSIZE(year))
{
dayno -= YEARSIZE(year);
year++;
}
tmbuf->tm_year = year - YEAR0;
tmbuf->tm_yday = dayno;
tmbuf->tm_mon = 0;
while (dayno >= (unsigned long) _ytab[LEAPYEAR(year)][tmbuf->tm_mon])
{
dayno -= _ytab[LEAPYEAR(year)][tmbuf->tm_mon];
tmbuf->tm_mon++;
}
tmbuf->tm_mday = dayno + 1;
tmbuf->tm_isdst = 0;

return tmbuf;
}

Linking with it gives correct printouts.
Seems it is worth replacing the original object in the "clib3r.lib" with
this one.

Tony
booBot
Senior Member
 
Posts: 633
Joined: Tue Feb 24, 2004 5:07 pm


Return to qnx.qnx4

Who is online

Users browsing this forum: No registered users and 1 guest