if (optarg) {
ctl.req.week = strtos32_or_err(optarg,
_("invalid week argument"));
- if (ctl.req.week < 1 || 53 < ctl.req.week)
- errx(EXIT_FAILURE,_("illegal week value: use 1-53"));
+ if (ctl.req.week < 1 || 54 < ctl.req.week)
+ errx(EXIT_FAILURE,_("illegal week value: use 1-54"));
}
ctl.weektype = WEEK_NUM_US; /* default per weekstart */
break;
int weeknum = week_number(1, month->month, month->year, ctl);
weeklines = MAXDAYS / DAYS_IN_WEEK - weeklines / DAYS_IN_WEEK;
for (i = 0; i < MAXDAYS / DAYS_IN_WEEK; i++) {
- if (0 < weeklines)
+ if (0 < weeklines) {
+ if (52 < weeknum)
+ weeknum = week_number(month->days[i * DAYS_IN_WEEK], month->month, month->year, ctl);
month->weeks[i] = weeknum++;
- else
+ } else
month->weeks[i] = SPACE;
weeklines--;
- if (i == 0 && (52 < weeknum || (month->year == 1753 && 51 < weeknum)))
- weeknum = week_number(month->days[DAYS_IN_WEEK * (i + 1)], 1, month->year, ctl);
- else if (52 < weeknum)
- weeknum = week_number(31, 12, month->year, ctl);
}
}
}
/*
* week_number
- * return the week number of a given date, 1..53.
+ * return the week number of a given date, 1..54.
* Supports ISO-8601 and North American modes.
* Day may be given as Julian day of the year mode, in which
* case the month is disregarded entirely.
static int week_number(int day, int month, int32_t year, const struct cal_control *ctl)
{
int fday = 0, yday;
- int wday = day_in_week(1, 1, year);
+ const int wday = day_in_week(1, 1, year);
if (ctl->weektype & WEEK_NUM_ISO)
fday = wday + (wday >= FRIDAY ? -2 : 5);
- else
- /* WEEK_NUM_US
- * - according to gcal, the first Sun is in the first week
- * - according to wikipedia, the first Sat is in the first week
- */
- fday = wday + (wday == SUNDAY ? 6 : -1);
-
+ else {
+ /* WEEK_NUM_US: Jan 1 is always First week, that may
+ * begin previous year. That means there is very seldom
+ * more than 52 weeks, */
+ fday = wday + 6;
+ }
/* For julian dates the month can be set to 1, the global julian
* variable cannot be relied upon here, because we may recurse
* internally for 31.12. which would not work. */
&& day_in_week(day, month, year) <= WEDNESDAY
&& day_in_week(31, 12, year) >= MONDAY
&& day_in_week(31, 12, year) <= WEDNESDAY)
- return week_number(1, 1, year + 1, ctl);
+ return week_number(1, 1, year + 1, ctl);
return (yday + fday) / 7;
}