#include #include #include #include #include #ifdef DOS long timezone = -1*60*60; #endif /* Returns non-zero if it failed, zero if OK. */ int week(int year, int month, int day, int *aweek, int *weekday) { struct tm timeCheck; time_t timeNowInSeconds; struct tm *timeNow; int yearNow; int WeekDay_I; int WeekNo_I; int FirstWeek_I; int YearDay_I; memset(&timeCheck, 0, sizeof(struct tm)); timeCheck.tm_year=year; timeCheck.tm_mon=month; timeCheck.tm_mday=day; timeNowInSeconds = mktime(&timeCheck); timeNow = localtime(&timeNowInSeconds); if(timeNow->tm_mon != month) { return 1; /* this is no longer the same month! */ } yearNow = timeNow->tm_year; /* struct tm stores yday 0 based, we need it 1 based */ YearDay_I = timeNow->tm_yday + 1; /* silly americans begin the week on sundays. ISO doesn't */ WeekDay_I = timeNow->tm_wday; if ( 0 == WeekDay_I ) /* if it's sunday, */ WeekDay_I = 7; /* make it sunday! */ WeekNo_I = YearDay_I / 7; FirstWeek_I = YearDay_I % 7; FirstWeek_I -= WeekDay_I; if ( ( FirstWeek_I <= 0 ) && ( WeekNo_I > 0 ) ) { /* break up one week and add the days to FirstWeek_I */ WeekNo_I--; FirstWeek_I += 7; } if ( FirstWeek_I > (-4) ) WeekNo_I += 1; if ( FirstWeek_I > 3 ) WeekNo_I += 1; if(0 == WeekNo_I) { /* same as previous year's last day: */ int fool; week(year - 1, 11 /* December is 11 */, 31, &WeekNo_I, &fool); } else if(WeekNo_I > 52) { /* the last days of the year */ if(WeekDay_I < 4 && day > 28) { /* Three or less days of this year in 53 makes it week 1 instead! */ WeekNo_I = 1; } } *aweek = WeekNo_I; *weekday = WeekDay_I; return 0; } /* * Mission: we have year and week number. What date does that week * start with? (i.e what's the date monday that week) */ int week_no(int year, int aweek, int *ret_month, int *ret_day) { int month; int day=15; int getweek; int getday; while (aweek > 53) aweek -= 53; month = 11 * aweek / 53; /* assume 53 weeks a year */ do { if (week(year, month, day, &getweek, &getday)) { month++; day=1; continue; } #if 0 printf("Year %d Month %d Day %d Week %d WDay %d\n", year, month+1, day, getweek, getday); #endif if ((getweek>aweek-3) && (getweek1) day+=7; else day+=(8-getday); } else { if(getweek-aweek>1) day-=7; else if(getweek==aweek) { day-=getday-1; } else day-=getday+6; if(day<=0) { day=28; month--; } } } else { if(++month>11) { day=0; month=0; break; } } } while(1); *ret_day=day; *ret_month=month+1; return 0; } #if defined(SELF) || defined(SELFTEST) || defined(SELF_WEEK) int main(int argc, char **argv) { int WeekNo_I, WeekDay_I; if (argc < 4) { puts("Enter [YYYY] [MM] [DD]"); return 1; } if (! strcasecmp(argv[1], "week")) { week_no(atoi(argv[2])-1900, atoi(argv[3]), &WeekNo_I, &WeekDay_I); if(WeekDay_I>0) { printf("Month %02d Day %02d\n", WeekNo_I, WeekDay_I); } else { printf("No monday in such a week that year!\n"); } } else { if (! week(atoi(argv[1])-1900, atoi(argv[2])-1, atoi(argv[3]), &WeekNo_I, &WeekDay_I)) { printf("Week %d Weekday %d\n", WeekNo_I, WeekDay_I); } else printf("Illegal date!\n"); } return 0; } #endif