[BUG][FIX] primSecondsClock ( sqWin32Directory.c -- Windows only)

John Clonts jclonts at mastnet.net
Thu Mar 2 18:33:40 UTC 2000


The bug is in 

   convertToSqueakTime()

The fix is to replace

   if(st.wMonth > 2 && (dy & 0x0003) == 0)  // line 24

with

   if(st.wMonth > 2 && (++dy & 0x0003) == 0)  // line 24

Attached is a unit test which demonstrates the bug and fix.

Cheers,
John


P.S. should this have gone to the mailing list or just to Andreas Raab?
-------------- next part --------------
/*
trying to figure out why March 2 shows as March 1
*/
#include <afx.h>
#include <time.h>
#include <iostream>
using namespace std;

int failures=0;
bool useTheNewOne;

/* from sqWin32Directory.c */
DWORD convertToSqueakTime(SYSTEMTIME st)
{ DWORD secs;
  DWORD dy;
  static DWORD nDaysPerMonth[14] = { 
    0,  0,  31,  59,  90, 120, 151,
      181, 212, 243, 273, 304, 334, 365 };
  /* Squeak epoch is Jan 1, 1901 */
  dy = st.wYear - 1901; /* compute delta year */
  secs = dy * 365 * 24 * 60 * 60       /* base seconds */
         + (dy >> 2) * 24 * 60 * 60;   /* seconds of leap years */
  /* check if month > 2 and current year is a leap year */
  if(st.wMonth > 2 && (dy & 0x0003) == 0)
    secs += 24 * 60 * 60; /* add one day */
  /* add the days from the beginning of the year */
  secs += (nDaysPerMonth[st.wMonth] + st.wDay - 1) * 24 * 60 * 60;
  /* add the hours, minutes, and seconds */
  secs += st.wSecond + 60*(st.wMinute + 60*st.wHour);
  return secs;
}

DWORD myNewConvertToSqueakTime(SYSTEMTIME st)
{ DWORD secs;
  DWORD dy;
  static DWORD nDaysPerMonth[14] = { 
    0,  0,  31,  59,  90, 120, 151,
      181, 212, 243, 273, 304, 334, 365 };
  /* Squeak epoch is Jan 1, 1901 */
  dy = st.wYear - 1901; /* compute delta year */
  secs = dy * 365 * 24 * 60 * 60       /* base seconds */
		+ (dy >> 2) * 24 * 60 * 60;   /* seconds of leap years */
  /* check if month > 2 and current year is a leap year */
  if(st.wMonth > 2 && (++dy & 0x0003) == 0)
    secs += 24 * 60 * 60; /* add one day */
  /* add the days from the beginning of the year */
  secs += (nDaysPerMonth[st.wMonth] + st.wDay - 1) * 24 * 60 * 60;
  /* add the hours, minutes, and seconds */
  secs += st.wSecond + 60*(st.wMinute + 60*st.wHour);
  return secs;
}


/* from sqWin32Window.c */
unsigned int ioSeconds(void)
{ SYSTEMTIME sysTime;
  GetLocalTime(&sysTime);
  return convertToSqueakTime(sysTime);
}

unsigned int time_ttime(time_t ltime)
{
 	/* Squeak epoch is Jan 1, 1901.  time() epoch is Jan 1, 1970: 17 leap years
     and 52 non-leap years later than Squeak. */
	return ltime + ((52*365UL + 17*366UL) * 24*60*60UL);
}

void time_tprint( time_t ltime)
{
    /* display as number and string. */
    printf( "Time in seconds since UTC 1/1/70:\t%ld\n", ltime );
    printf( "UNIX time and date:\t\t\t%s", ctime( &ltime ) );
	
}

unsigned int currSqueak( int yr, int mo , int day )
{
	SYSTEMTIME st;
	CTime ct( yr, mo, day, 0, 0, 0);
	ct.GetAsSystemTime( st);
	if (useTheNewOne)
		return myNewConvertToSqueakTime( st);
	else
		return convertToSqueakTime( st);
}

unsigned int winTime( int yr, int mo, int day)
{
	CTime ct( yr, mo, day, 0, 0, 0, /*dst=*/ 0);
	return time_ttime( ct.GetTime() - 6 * 3600 );
}

bool confirm( int yr, int mo , int day)
{
	// return true if confirmed, false if failed
	unsigned int wt = winTime( yr,mo,day);
	unsigned int st = currSqueak( yr,mo,day);
	long diff = wt-st;
	if ( wt != st )
		cout << "Fail " << yr << "/" << mo << "/" << day 
			<<" squeak: " << st << "  win: " << wt << " diff: " << diff << endl;
	return wt==st;
}

int main(int argc, char **argv)
{
	failures=0;
	useTheNewOne=(argc > 1);
	
	for ( int yr = 1971 ; yr < 2005 ; yr++)
	{
		confirm( yr, 2, 27);
		confirm( yr, 3, 2);
		
	}
	confirm( 2000, 1 , 1);
	confirm( 2000, 12 , 31);
	confirm( 2000, 2, 29);
	confirm( 2000, 3, 1);
	
	if (failures)
		cout << "Failures: " << failures << endl;
	else
		cout << "Success" << endl;
		
	return 0;	
}


More information about the Squeak-dev mailing list