⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclgetdate.y

📁 tcl是工具命令语言
💻 Y
📖 第 1 页 / 共 3 页
字号:
	return 0;    }    return DSTcorrect(Start, now);}static intRelativeMonth(Start, RelMonth, TimePtr)    time_t Start;    time_t RelMonth;    time_t *TimePtr;{    struct tm *tm;    time_t Month;    time_t Year;    time_t Julian;    int result;    if (RelMonth == 0) {        *TimePtr = 0;        return 0;    }    tm = TclpGetDate((TclpTime_t)&Start, 0);    Month = 12 * (tm->tm_year + TM_YEAR_BASE) + tm->tm_mon + RelMonth;    Year = Month / 12;    Month = Month % 12 + 1;    result = Convert(Month, (time_t) tm->tm_mday, Year,	    (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,	    MER24, DSTmaybe, &Julian);    /*     * The Julian time returned above is behind by one day, if "month"      * or "year" is used to specify relative time and the GMT flag is true.     * This problem occurs only when the current time is closer to     * midnight, the difference being not more than its time difference     * with GMT. For example, in US/Pacific time zone, the problem occurs     * whenever the current time is between midnight to 8:00am or 7:00amDST.     * See Bug# 413397 for more details and sample script.     * To resolve this bug, we simply add the number of seconds corresponding     * to timezone difference with GMT to Julian time, if GMT flag is true.     */    if (TclDateTimezone == 0) {        Julian += TclpGetTimeZone((unsigned long) Start) * 60L;    }    /*     * The following iteration takes into account the case were we jump     * into a "short month".  Far example, "one month from Jan 31" will     * fail because there is no Feb 31.  The code below will reduce the     * day and try converting the date until we succed or the date equals     * 28 (which always works unless the date is bad in another way).     */    while ((result != 0) && (tm->tm_mday > 28)) {	tm->tm_mday--;	result = Convert(Month, (time_t) tm->tm_mday, Year,		(time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,		MER24, DSTmaybe, &Julian);    }    if (result != 0) {	return -1;    }    *TimePtr = DSTcorrect(Start, Julian);    return 0;}/* *----------------------------------------------------------------------------- * * RelativeDay -- * *      Given a starting time and a number of days before or after, compute the *      DST corrected difference between those dates. * * Results: *     1 or -1 indicating success or failure. * * Side effects: *      Fills TimePtr with the computed value. * *----------------------------------------------------------------------------- */static intRelativeDay(Start, RelDay, TimePtr)    time_t Start;    time_t RelDay;    time_t *TimePtr;{    time_t new;    new = Start + (RelDay * 60 * 60 * 24);    *TimePtr = DSTcorrect(Start, new);    return 1;}static intLookupWord(buff)    char                *buff;{    register char *p;    register char *q;    register TABLE *tp;    int i;    int abbrev;    /*     * Make it lowercase.     */    Tcl_UtfToLower(buff);    if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {        yylval.Meridian = MERam;        return tMERIDIAN;    }    if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {        yylval.Meridian = MERpm;        return tMERIDIAN;    }    /*     * See if we have an abbreviation for a month.     */    if (strlen(buff) == 3) {        abbrev = 1;    } else if (strlen(buff) == 4 && buff[3] == '.') {        abbrev = 1;        buff[3] = '\0';    } else {        abbrev = 0;    }    for (tp = MonthDayTable; tp->name; tp++) {        if (abbrev) {            if (strncmp(buff, tp->name, 3) == 0) {                yylval.Number = tp->value;                return tp->type;            }        } else if (strcmp(buff, tp->name) == 0) {            yylval.Number = tp->value;            return tp->type;        }    }    for (tp = TimezoneTable; tp->name; tp++) {        if (strcmp(buff, tp->name) == 0) {            yylval.Number = tp->value;            return tp->type;        }    }    for (tp = UnitsTable; tp->name; tp++) {        if (strcmp(buff, tp->name) == 0) {            yylval.Number = tp->value;            return tp->type;        }    }    /*     * Strip off any plural and try the units table again.     */    i = strlen(buff) - 1;    if (buff[i] == 's') {        buff[i] = '\0';        for (tp = UnitsTable; tp->name; tp++) {            if (strcmp(buff, tp->name) == 0) {                yylval.Number = tp->value;                return tp->type;            }	}    }    for (tp = OtherTable; tp->name; tp++) {        if (strcmp(buff, tp->name) == 0) {            yylval.Number = tp->value;            return tp->type;        }    }    /*     * Military timezones.     */    if (buff[1] == '\0' && !(*buff & 0x80)	    && isalpha(UCHAR(*buff))) {	/* INTL: ISO only */        for (tp = MilitaryTable; tp->name; tp++) {            if (strcmp(buff, tp->name) == 0) {                yylval.Number = tp->value;                return tp->type;            }	}    }    /*     * Drop out any periods and try the timezone table again.     */    for (i = 0, p = q = buff; *q; q++)        if (*q != '.') {            *p++ = *q;        } else {            i++;	}    *p = '\0';    if (i) {        for (tp = TimezoneTable; tp->name; tp++) {            if (strcmp(buff, tp->name) == 0) {                yylval.Number = tp->value;                return tp->type;            }	}    }        return tID;}static intyylex(){    register char       c;    register char       *p;    char                buff[20];    int                 Count;    for ( ; ; ) {        while (isspace(UCHAR(*yyInput))) {            yyInput++;	}        if (isdigit(UCHAR(c = *yyInput))) { /* INTL: digit */	    /* convert the string into a number; count the number of digits */	    Count = 0;            for (yylval.Number = 0;		    isdigit(UCHAR(c = *yyInput++)); ) { /* INTL: digit */                yylval.Number = 10 * yylval.Number + c - '0';		Count++;	    }            yyInput--;	    /* A number with 6 or more digits is considered an ISO 8601 base */	    if (Count >= 6) {		return tISOBASE;	    } else {		return tUNUMBER;	    }        }        if (!(c & 0x80) && isalpha(UCHAR(c))) {	/* INTL: ISO only. */            for (p = buff; isalpha(UCHAR(c = *yyInput++)) /* INTL: ISO only. */		     || c == '.'; ) {                if (p < &buff[sizeof buff - 1]) {                    *p++ = c;		}	    }            *p = '\0';            yyInput--;            return LookupWord(buff);        }        if (c != '(') {            return *yyInput++;	}        Count = 0;        do {            c = *yyInput++;            if (c == '\0') {                return c;	    } else if (c == '(') {                Count++;	    } else if (c == ')') {                Count--;	    }        } while (Count > 0);    }}/* * Specify zone is of -50000 to force GMT.  (This allows BST to work). */intTclGetDate(p, now, zone, timePtr)    char *p;    unsigned long now;    long zone;    unsigned long *timePtr;{    struct tm *tm;    time_t Start;    time_t Time;    time_t tod;    int thisyear;    yyInput = p;    /* now has to be cast to a time_t for 64bit compliance */    Start = now;    tm = TclpGetDate((TclpTime_t) &Start, 0);    thisyear = tm->tm_year + TM_YEAR_BASE;    yyYear = thisyear;    yyMonth = tm->tm_mon + 1;    yyDay = tm->tm_mday;    yyTimezone = zone;    if (zone == -50000) {        yyDSTmode = DSToff;  /* assume GMT */        yyTimezone = 0;    } else {        yyDSTmode = DSTmaybe;    }    yyHour = 0;    yyMinutes = 0;    yySeconds = 0;    yyMeridian = MER24;    yyRelSeconds = 0;    yyRelMonth = 0;    yyRelDay = 0;    yyRelPointer = NULL;    yyHaveDate = 0;    yyHaveDay = 0;    yyHaveOrdinalMonth = 0;    yyHaveRel = 0;    yyHaveTime = 0;    yyHaveZone = 0;    if (yyparse() || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 ||	    yyHaveDay > 1 || yyHaveOrdinalMonth > 1) {        return -1;    }        if (yyHaveDate || yyHaveTime || yyHaveDay) {	if (TclDateYear < 0) {	    TclDateYear = -TclDateYear;	}	/*	 * The following line handles years that are specified using	 * only two digits.  The line of code below implements a policy	 * defined by the X/Open workgroup on the millinium rollover.	 * Note: some of those dates may not actually be valid on some	 * platforms.  The POSIX standard startes that the dates 70-99	 * shall refer to 1970-1999 and 00-38 shall refer to 2000-2038.	 * This later definition should work on all platforms.	 */	if (TclDateYear < 100) {	    if (TclDateYear >= 69) {		TclDateYear += 1900;	    } else {		TclDateYear += 2000;	    }	}	if (Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,		yyMeridian, yyDSTmode, &Start) < 0) {            return -1;	}    } else {        Start = now;        if (!yyHaveRel) {            Start -= ((tm->tm_hour * 60L * 60L) +		    tm->tm_min * 60L) +	tm->tm_sec;	}    }    Start += yyRelSeconds;    if (RelativeMonth(Start, yyRelMonth, &Time) < 0) {        return -1;    }    Start += Time;    if (RelativeDay(Start, yyRelDay, &Time) < 0) {	return -1;    }    Start += Time;        if (yyHaveDay && !yyHaveDate) {        tod = NamedDay(Start, yyDayOrdinal, yyDayNumber);        Start += tod;    }    if (yyHaveOrdinalMonth) {	tod = NamedMonth(Start, yyMonthOrdinal, yyMonth);	Start += tod;    }        *timePtr = Start;    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -