Пример #1
0
int
week(int day, int month, int year)
{
	int	yearday;
	int	firstweekday;
	int	weekday;
	int	firstday;
	int	firstsunday;
	int	shift;
	
	if (mflag)
		return isoweek(day, month, year);

	yearday = day_in_year(day, month, year);
	firstweekday = day_in_week(1, 1, year) + 1;
	weekday = day_in_week(day, month, year) + 1;
	firstday = day_in_year(1, 1, year);
	firstsunday = firstday + (8 - firstweekday);

	shift = 1;
	if (yearday < firstsunday)
		return (1);
	if (firstweekday > THURSDAY - 1) 
		shift = 2;
	return ((((yearday + 1) - (weekday - 1)) / 7) + shift);
}
Пример #2
0
/*
 * day_array --
 *	Fill in an array of 42 integers with a calendar.  Assume for a moment
 *	that you took the (maximum) 6 rows in a calendar and stretched them
 *	out end to end.  You would have 42 numbers or spaces.  This routine
 *	builds that array for any month from Jan. 1 through Dec. 9999.
 */
void
day_array(int day, int month, int year, int *days) {
	int julday, daynum, dw, dm;
	int *d_sep1752;

	if (month == 9 && year == 1752) {
		int sep1752_ofs = (weekstart + SEP1752_OFS) % 7;
		d_sep1752 = julian ? j_sep1752 : sep1752;
		memcpy(days, d_sep1752 + sep1752_ofs, MAXDAYS * sizeof(int));
		for (dm=0; dm<MAXDAYS; dm++)
			if (j_sep1752[dm + sep1752_ofs] == day)
				days[dm] |= TODAY_FLAG;
		return;
	}
	memcpy(days, empty, MAXDAYS * sizeof(int));
	dm = days_in_month[leap_year(year)][month];
	dw = (day_in_week(1, month, year) - weekstart + 7) % 7;
	julday = day_in_year(1, month, year);
	daynum = julian ? julday : 1;
	while (dm--) {
		days[dw] = daynum++;
		if (julday++ == day)
			days[dw] |= TODAY_FLAG;
		dw++;
	}
}
Пример #3
0
/*
 * day_in_week
 *	return the 0 based day number for any date from 1 Jan. 1 to
 *	31 Dec. 9999.  Assumes the Gregorian reformation eliminates
 *	3 Sep. 1752 through 13 Sep. 1752.  Returns Thursday for all
 *	missing days.
 */
int
day_in_week(int day, int month, int year) {
	long temp;

	temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1)
	    + day_in_year(day, month, year);
	if (temp < FIRST_MISSING_DAY)
		return ((temp - 1 + SATURDAY) % 7);
	if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS))
		return (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7);
	return (THURSDAY);
}
Пример #4
0
/*
 * day_array --
 *	Fill in an array of 42 integers with a calendar.  Assume for a moment
 *	that you took the (maximum) 6 rows in a calendar and stretched them
 *	out end to end.  You would have 42 numbers or spaces.  This routine
 *	builds that array for any month from Jan. 1 through Dec. 9999.
 */
void
day_array(int month, int year, int *days)
{
	int day, dw, dm;

	if (month == 9 && year == 1752) {
		memmove(days, sep1752, MAXDAYS * sizeof(int));
		return;
	}
	memmove(days, empty, MAXDAYS * sizeof(int));
	dm = days_in_month[leap_year(year)][month];
	dw = day_in_week(mflag?0:1, month, year);
	day = julian ? day_in_year(1, month, year) : 1;
	while (dm--)
		days[dw++] = day++;
}
Пример #5
0
 // number of days since Jan 1, 1970 (day 0)
 long int days_linear(const Date& d)
 {
     if (d.year() < first_date.year()) error("days_linear: year must be 1970 or later");
     int y = d.year() - first_date.year();
     return y*365 + n_leapyears(d.year()) + day_in_year(d) - 1;
 }
Пример #6
0
int
main(int argc, char **argv) {
	struct tm *local_time;
	time_t now;
	int ch, day, month, year, yflag;
	char *progname, *p;
	int num_months = NUM_MONTHS;

	progname = argv[0];
	if ((p = strrchr(progname, '/')) != NULL)
		progname = p+1;
	__progname = progname;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

#if defined(HAVE_LIBNCURSES) || defined(HAVE_LIBNCURSESW) || defined(HAVE_LIBTERMCAP)
	if ((term = getenv("TERM"))) {
		int ret;
		my_setupterm(term, 1, &ret);
		if (ret > 0) {
			Senter = my_tgetstr("so","smso");
			Sexit = my_tgetstr("se","rmso");
			Slen = strlen(Senter) + strlen(Sexit);
		}
	}
#endif

/*
 * The traditional Unix cal utility starts the week at Sunday,
 * while ISO 8601 starts at Monday. We read the start day from
 * the locale database, which can be overridden with the
 * -s (Sunday) or -m (Monday) options.
 */
#if HAVE_DECL__NL_TIME_WEEK_1STDAY
	/*
	 * You need to use 2 locale variables to get the first day of the week.
	 * This is needed to support first_weekday=2 and first_workday=1 for
	 * the rare case where working days span across 2 weeks.
	 * This shell script shows the combinations and calculations involved:

	 for LANG in en_US ru_RU fr_FR csb_PL POSIX; do
	   printf "%s:\t%s + %s -1 = " $LANG $(locale week-1stday first_weekday)
	   date -d"$(locale week-1stday) +$(($(locale first_weekday)-1))day" +%w
	 done

	 en_US:  19971130 + 1 -1 = 0  #0 = sunday
	 ru_RU:  19971130 + 2 -1 = 1
	 fr_FR:  19971201 + 1 -1 = 1
	 csb_PL: 19971201 + 2 -1 = 2
	 POSIX:  19971201 + 7 -1 = 0
	 */
	{
		int wfd;
		union { unsigned int word; char *string; } val;
		val.string = nl_langinfo(_NL_TIME_WEEK_1STDAY);

		wfd = val.word;
		wfd = day_in_week(wfd % 100, (wfd / 100) % 100, wfd / (100 * 100));
		weekstart = (wfd + *nl_langinfo(_NL_TIME_FIRST_WEEKDAY) - 1) % 7;
	}
#endif

	yflag = 0;
	while ((ch = getopt(argc, argv, "13mjsyV")) != -1)
		switch(ch) {
		case '1':
			num_months = 1;		/* default */
			break;
		case '3':
			num_months = 3;
			break;
		case 's':
			weekstart = 0;		/* default */
			break;
		case 'm':
			weekstart = 1;
			break;
		case 'j':
			julian = 1;
			break;
		case 'y':
			yflag = 1;
			break;
		case 'V':
			printf(_("%s from %s\n"),
			       progname, PACKAGE_STRING);
			return 0;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	time(&now);
	local_time = localtime(&now);

	day = month = year = 0;
	switch(argc) {
	case 3:
		if ((day = atoi(*argv++)) < 1 || day > 31)
			errx(1, _("illegal day value: use 1-%d"), 31);
		/* FALLTHROUGH */
	case 2:
		if ((month = atoi(*argv++)) < 1 || month > 12)
			errx(1, _("illegal month value: use 1-12"));
		/* FALLTHROUGH */
	case 1:
		if ((year = atoi(*argv)) < 1 || year > 9999)
			errx(1, _("illegal year value: use 1-9999"));
		if (day) {
			int dm = days_in_month[leap_year(year)][month];
			if (day > dm)
				errx(1, _("illegal day value: use 1-%d"), dm);
			day = day_in_year(day, month, year);
		} else if ((local_time->tm_year + 1900) == year) {
			day = local_time->tm_yday + 1;
		}
		if (!month)
			yflag=1;
		break;
	case 0:
		day = local_time->tm_yday + 1;
		year = local_time->tm_year + 1900;
		month = local_time->tm_mon + 1;
		break;
	default:
		usage();
	}
	headers_init();

	if (!isatty(1))
		day = 0; /* don't highlight */

	if (yflag && julian)
		j_yearly(day, year);
	else if (yflag)
		yearly(day, year);
	else if (num_months == 1)
		monthly(day, month, year);
	else if (num_months == 3)
		monthly3(day, month, year);
	exit(0);
}