/* Convert an ISO8601:1988 week number to the date of the start of * that week (i.e. the Monday) * * Andrew Benham, June 1998 */ #include #include #include #include int main(int argc, char **argv) { char *cp,tmp[5]; int year,week; struct tm tm; time_t t; /* Check the single parameter is valid, e.g. 1998W27 */ if (argc != 2){ fprintf(stderr,"Syntax: whenis yyyyWww\n"); return 1; } if ((strlen(argv[1]) != 7) || (argv[1][4] != 'W')) { fprintf(stderr,"Syntax error: need yyyyWww\n"); return 1; } /* Extract the year and week numbers */ strncpy(tmp,argv[1],4); year=atoi(tmp); cp = argv[1]+5; strcpy(tmp,cp); week=atoi(tmp); /* Range checks */ if (year < 1970 || year > 2037) { fprintf(stderr,"Year %04d out of range\n",year); return 1; } if (week < 1 || week > 53) { fprintf(stderr,"Week %02d out of range\n",week); return 1; } /* ISO8601:1988 week numbers guarantee that 4 Jan is in week 01 * * Set the struct tm up with 4 January */ tm.tm_year=year-1900; tm.tm_mon=0; tm.tm_mday=4; tm.tm_hour=12; tm.tm_min=0; tm.tm_sec=0; tm.tm_isdst=-1; /* Now bump the day of the month up by (1 minus the week number) * number of weeks */ tm.tm_mday+=(7*(week-1)); /* Call mktime() to fixup the date fields, and set day of week */ t=mktime(&tm); /* Move Sunday to the end of the week */ if (tm.tm_wday == 0) { tm.tm_wday = 7; } /* Drop the day of the month back to the Monday of the week */ tm.tm_mday -= (tm.tm_wday -1); /* Call mktime() to fixup the date fields again */ t=mktime(&tm); /* Check whether week 53 is valid for the given year */ if (week == 53) { /* Valid week 53s start on 27 or 28 December */ if ((tm.tm_mon != 11) || (tm.tm_mday != 27 && tm.tm_mday != 28)) { /* If not valid, return -1/-1/year * * The month number gets incremented in the printf() */ tm.tm_mday=-1; tm.tm_mon=-2; } } printf("%02d/%02d/%04d\n",tm.tm_mday,1+tm.tm_mon,1900+tm.tm_year); return 0; }