[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( <ime ) );
}
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
|