예제 #1
0
/* 
 * month() picks apart a month specification
 *
 *  /[<month> NUMBER [NUMBER]]           \
 *  |[TOMORROW]                          |
 *  |[DAY OF WEEK]                       |
 *  |NUMBER [SLASH NUMBER [SLASH NUMBER]]|
 *  \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/
 */
static void
month(struct tm *tm)
{
    long year= (-1);
    long mday = 0, wday, mon;
    int tlen;

    switch (sc_tokid) {
    case PLUS:
	    plus(tm);
	    break;

    case TOMORROW:
	    /* do something tomorrow */
	    tm->tm_mday ++;
	    tm->tm_wday ++;
    case TODAY:	/* force ourselves to stay in today - no further processing */
	    token();
	    break;

    case JAN: case FEB: case MAR: case APR: case MAY: case JUN:
    case JUL: case AUG: case SEP: case OCT: case NOV: case DEC:
	    /* do month mday [,year]
	     */
	    mon = (sc_tokid-JAN);
	    expect(NUMBER);
	    mday = atol(sc_token);
	    if (token() == COMMA) {
		if (token() == NUMBER) {
		    year = atol(sc_token);
		    token();
		}
	    }
	    assign_date(tm, mday, mon, year);
	    if (sc_tokid == PLUS)
		    plus(tm);
	    break;

    case SUN: case MON: case TUE:
    case WED: case THU: case FRI:
    case SAT:
	    /* do a particular day of the week
	     */
	    wday = (sc_tokid-SUN);

	    mday = tm->tm_mday;

	    /* if this day is < today, then roll to next week
	     */
	    if (wday < tm->tm_wday)
		mday += 7 - (tm->tm_wday - wday);
	    else
		mday += (wday - tm->tm_wday);

	    tm->tm_wday = wday;

	    assign_date(tm, mday, tm->tm_mon, tm->tm_year);
	    break;

    case NUMBER:
	    /* get numeric MMDDYY, mm/dd/yy, or dd.mm.yy
	     */
	    tlen = strlen(sc_token);
	    mon = atol(sc_token);
	    token();

	    if (sc_tokid == SLASH || sc_tokid == DOT) {
		int sep;

		sep = sc_tokid;
		expect(NUMBER);
		mday = atol(sc_token);
		if (token() == sep) {
		    expect(NUMBER);
		    year = atol(sc_token);
		    token();
		}

		/* flip months and days for European timing
		 */
		if (sep == DOT) {
		    int x = mday;
		    mday = mon;
		    mon = x;
		}
	    }
	    else if (tlen == 6 || tlen == 8) {
		if (tlen == 8) {
		    year = (mon % 10000) - TM_YEAR_BASE;
		    mon /= 10000;
		}
		else {
		    year = mon % 100;
		    mon /= 100;
		}
		mday = mon % 100;
		mon /= 100;
	    }
	    else
		panic("garbled time");

	    mon--;
	    if (mon < 0 || mon > 11 || mday < 1 || mday > 31)
		panic("garbled time");

	    assign_date(tm, mday, mon, year);
	    break;
    } /* case */
} /* month */
예제 #2
0
파일: date_test.c 프로젝트: never-wang/Aunt
END_TEST

START_TEST(test_cal_interval)
{
    date_t d1, d2;
    int interval;

    init_date(&d1);
    init_date(&d2);

    assign_date(&d1, 2012, 2, 20);
    assign_date(&d2, 2012, 3, 20);

    aunt_date_cal_interval(&interval, &d1, &d2);
    fail_unless((interval == 29), "calculate interval between"
	    "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly",
	    d1.year, d1.month, d1.day, d1.year, d1.month, d1.day);
    
    assign_date(&d1, 2012, 3, 20);
    assign_date(&d2, 2012, 2, 20);

    aunt_date_cal_interval(&interval, &d1, &d2);
    fail_unless((interval == 29), "calculate interval between"
	    "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly",
	    d1.year, d1.month, d1.day, d1.year, d1.month, d1.day);
    
    assign_date(&d1, 2013, 2, 20);
    assign_date(&d2, 2013, 3, 20);

    aunt_date_cal_interval(&interval, &d1, &d2);
    fail_unless((interval == 28), "calculate interval between"
	    "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly",
	    d1.year, d1.month, d1.day, d1.year, d1.month, d1.day);
    
    assign_date(&d1, 2013, 3, 20);
    assign_date(&d2, 2013, 2, 20);

    aunt_date_cal_interval(&interval, &d1, &d2);
    fail_unless((interval == 28), "calculate interval between"
	    "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly",
	    d1.year, d1.month, d1.day, d1.year, d1.month, d1.day);
    
    assign_date(&d1, 2012, 2, 1);
    assign_date(&d2, 2012, 2, 28);

    aunt_date_cal_interval(&interval, &d1, &d2);
    fail_unless((interval == 27), "calculate interval between"
	    "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly",
	    d1.year, d1.month, d1.day, d1.year, d1.month, d1.day);
    
    assign_date(&d1, 2012, 2, 28);
    assign_date(&d2, 2012, 2, 1);

    aunt_date_cal_interval(&interval, &d1, &d2);
    fail_unless((interval == 27), "calculate interval between"
	    "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly",
	    d1.year, d1.month, d1.day, d1.year, d1.month, d1.day);
    
    assign_date(&d1, 2012, 12, 15);
    assign_date(&d2, 2013, 1, 16);

    aunt_date_cal_interval(&interval, &d1, &d2);
    fail_unless((interval == 32), "calculate interval between"
	    "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly",
	    d1.year, d1.month, d1.day, d1.year, d1.month, d1.day);
    
    assign_date(&d1, 2013, 1, 15);
    assign_date(&d2, 2012, 12, 16);

    aunt_date_cal_interval(&interval, &d1, &d2);
    fail_unless((interval == 30), "calculate interval between"
	    "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly",
	    d1.year, d1.month, d1.day, d1.year, d1.month, d1.day);
}
예제 #3
0
/*
 * month() picks apart a month specification
 *
 *  /[<month> NUMBER [NUMBER]]           \
 *  |[TOMORROW]                          |
 *  |[DAY OF WEEK]                       |
 *  |NUMBER [SLASH NUMBER [SLASH NUMBER]]|
 *  \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/
 */
static void
month(struct tm *tm)
{
	int year;
	int mday, wday, mon;
	size_t tlen;

	year = -1;
	mday = 0;
	switch (sc_tokid) {
	case PLUS:
		plus(tm);
		break;

	case TOMORROW:
		/* do something tomorrow */
		tm->tm_mday++;
		tm->tm_wday++;
		/*FALLTHROUGH*/
	case TODAY:
		/* force ourselves to stay in today - no further processing */
		(void)token();
		break;

	case JAN: case FEB: case MAR: case APR: case MAY: case JUN:
	case JUL: case AUG: case SEP: case OCT: case NOV: case DEC:
		/*
		 * do month mday [year]
		 */
		mon = sc_tokid - JAN;
		expect(NUMBER);
		mday = atoi(sc_token);
		if (token() == NUMBER) {
			year = atoi(sc_token);
			(void)token();
		}
		assign_date(tm, mday, mon, year);
		break;

	case SUN: case MON: case TUE:
	case WED: case THU: case FRI:
	case SAT:
		/* do a particular day of the week */
		wday = sc_tokid - SUN;

		mday = tm->tm_mday;

		/* if this day is < today, then roll to next week */
		if (wday < tm->tm_wday)
			mday += 7 - (tm->tm_wday - wday);
		else
			mday += (wday - tm->tm_wday);

		tm->tm_wday = wday;

		assign_date(tm, mday, tm->tm_mon, tm->tm_year + TM_YEAR_BASE);
		break;

	case NUMBER:
		/*
		 * get numeric MMDDYY, mm/dd/yy, or dd.mm.yy
		 */
		tlen = strlen(sc_token);
		mon = atoi(sc_token);
		(void)token();

		if (sc_tokid == SLASH || sc_tokid == DOT) {
			tokid_t sep;

			sep = sc_tokid;
			expect(NUMBER);
			mday = atoi(sc_token);
			if (token() == sep) {
				expect(NUMBER);
				year = atoi(sc_token);
				(void)token();
			}

			/*
			 * flip months and days for european timing
			 */
			if (sep == DOT) {
				int x = mday;
				mday = mon;
				mon = x;
			}
		} else if (tlen == 6 || tlen == 8) {
			if (tlen == 8) {
				year = (mon % 10000) - 1900;
				mon /= 10000;
			} else {
				year = mon % 100;
				mon /= 100;
			}
			mday = mon % 100;
			mon /= 100;
		} else
			panic("garbled time");

		mon--;
		if (mon < 0 || mon > 11 || mday < 1 || mday > 31)
			panic("garbled time");

		assign_date(tm, mday, mon, year);
		break;
	default:
		/* plonk(sc_tokid); */	/* XXX - die here? */
		break;
	}
}