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

📄 datetime.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
							tmask = DTK_M(MINUTE);							break;						case DTK_SECOND:							tm->tm_sec = val;							tmask = DTK_M(SECOND);							if (*cp == '.')							{								double		frac;								frac = strtod(cp, &cp);								if (*cp != '\0')									return DTERR_BAD_FORMAT;#ifdef HAVE_INT64_TIMESTAMP								*fsec = rint(frac * 1000000);#else								*fsec = frac;#endif							}							break;						case DTK_TZ:							tmask = DTK_M(TZ);							dterr = DecodeTimezone(field[i], tzp);							if (dterr)								return dterr;							break;						case DTK_JULIAN:							/***							 * previous field was a label for "julian date"?							 ***/							tmask = DTK_DATE_M;							j2date(val, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);							if (*cp == '.')							{								double		time;								time = strtod(cp, &cp);								if (*cp != '\0')									return DTERR_BAD_FORMAT;								tmask |= DTK_TIME_M;#ifdef HAVE_INT64_TIMESTAMP								dt2time(time * USECS_PER_DAY,								&tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);#else								dt2time(time * SECS_PER_DAY,								&tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);#endif							}							break;						case DTK_TIME:							/* previous field was "t" for ISO time */							dterr = DecodeNumberField(strlen(field[i]), field[i],													  (fmask | DTK_DATE_M),													  &tmask, tm,													  fsec, &is2digits);							if (dterr < 0)								return dterr;							ftype[i] = dterr;							if (tmask != DTK_TIME_M)								return DTERR_BAD_FORMAT;							break;						default:							return DTERR_BAD_FORMAT;							break;					}					ptype = 0;					*dtype = DTK_DATE;				}				else				{					char	   *cp;					int			flen;					flen = strlen(field[i]);					cp = strchr(field[i], '.');					/* Embedded decimal? */					if (cp != NULL)					{						/*						 * Under limited circumstances, we will accept a						 * date...						 */						if (i == 0 && nf >= 2 && ftype[nf - 1] == DTK_DATE)						{							dterr = DecodeDate(field[i], fmask, &tmask, tm);							if (dterr)								return dterr;						}						/* embedded decimal and several digits before? */						else if (flen - strlen(cp) > 2)						{							/*							 * Interpret as a concatenated date or time Set							 * the type field to allow decoding other fields							 * later. Example: 20011223 or 040506							 */							dterr = DecodeNumberField(flen, field[i],													  (fmask | DTK_DATE_M),													  &tmask, tm,													  fsec, &is2digits);							if (dterr < 0)								return dterr;							ftype[i] = dterr;						}						else							return DTERR_BAD_FORMAT;					}					else if (flen > 4)					{						dterr = DecodeNumberField(flen, field[i],												  (fmask | DTK_DATE_M),												  &tmask, tm,												  fsec, &is2digits);						if (dterr < 0)							return dterr;						ftype[i] = dterr;					}					/* otherwise it is a single date/time field... */					else					{						dterr = DecodeNumber(flen, field[i],											 FALSE,											 (fmask | DTK_DATE_M),											 &tmask, tm,											 fsec, &is2digits);						if (dterr)							return dterr;					}				}				break;			case DTK_STRING:			case DTK_SPECIAL:				type = DecodeSpecial(i, field[i], &val);				if (type == IGNORE_DTF)					continue;				tmask = DTK_M(type);				switch (type)				{					case RESERV:						switch (val)						{							case DTK_CURRENT:								ereport(ERROR,									 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),									  errmsg("date/time value \"current\" is no longer supported")));								return DTERR_BAD_FORMAT;								break;							case DTK_NOW:								tmask = DTK_TIME_M;								*dtype = DTK_TIME;								GetCurrentTimeUsec(tm, fsec, NULL);								break;							case DTK_ZULU:								tmask = (DTK_TIME_M | DTK_M(TZ));								*dtype = DTK_TIME;								tm->tm_hour = 0;								tm->tm_min = 0;								tm->tm_sec = 0;								tm->tm_isdst = 0;								break;							default:								return DTERR_BAD_FORMAT;						}						break;					case DTZMOD:						/*						 * daylight savings time modifier (solves "MET DST"						 * syntax)						 */						tmask |= DTK_M(DTZ);						tm->tm_isdst = 1;						if (tzp == NULL)							return DTERR_BAD_FORMAT;						*tzp += val * MINS_PER_HOUR;						break;					case DTZ:						/*						 * set mask for TZ here _or_ check for DTZ later when						 * getting default timezone						 */						tmask |= DTK_M(TZ);						tm->tm_isdst = 1;						if (tzp == NULL)							return DTERR_BAD_FORMAT;						*tzp = val * MINS_PER_HOUR;						ftype[i] = DTK_TZ;						break;					case TZ:						tm->tm_isdst = 0;						if (tzp == NULL)							return DTERR_BAD_FORMAT;						*tzp = val * MINS_PER_HOUR;						ftype[i] = DTK_TZ;						break;					case IGNORE_DTF:						break;					case AMPM:						mer = val;						break;					case UNITS:						tmask = 0;						ptype = val;						break;					case ISOTIME:						tmask = 0;						/***						 * We will need one of the following fields:						 *	DTK_NUMBER should be hhmmss.fff						 *	DTK_TIME should be hh:mm:ss.fff						 *	DTK_DATE should be hhmmss-zz						 ***/						if (i >= nf - 1 ||							(ftype[i + 1] != DTK_NUMBER &&							 ftype[i + 1] != DTK_TIME &&							 ftype[i + 1] != DTK_DATE))							return DTERR_BAD_FORMAT;						ptype = val;						break;					default:						return DTERR_BAD_FORMAT;				}				break;			default:				return DTERR_BAD_FORMAT;		}		if (tmask & fmask)			return DTERR_BAD_FORMAT;		fmask |= tmask;	}	if (mer != HR24 && tm->tm_hour > 12)		return DTERR_FIELD_OVERFLOW;	if (mer == AM && tm->tm_hour == 12)		tm->tm_hour = 0;	else if (mer == PM && tm->tm_hour != 12)		tm->tm_hour += 12;	if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_min > 59 ||		tm->tm_sec < 0 || tm->tm_sec > 60 || tm->tm_hour > 24 ||	/* test for > 24:00:00 */		(tm->tm_hour == 24 && (tm->tm_min > 0 || tm->tm_sec > 0 ||#ifdef HAVE_INT64_TIMESTAMP							   *fsec > INT64CONST(0))) ||		*fsec < INT64CONST(0) || *fsec >= USECS_PER_SEC)		return DTERR_FIELD_OVERFLOW;#else							   *fsec > 0)) ||		*fsec < 0 || *fsec >= 1)		return DTERR_FIELD_OVERFLOW;#endif	if ((fmask & DTK_TIME_M) != DTK_TIME_M)		return DTERR_BAD_FORMAT;	/* timezone not specified? then find local timezone if possible */	if (tzp != NULL && !(fmask & DTK_M(TZ)))	{		struct pg_tm tt,				   *tmp = &tt;		/*		 * daylight savings time modifier but no standard timezone? then error		 */		if (fmask & DTK_M(DTZMOD))			return DTERR_BAD_FORMAT;		if ((fmask & DTK_DATE_M) == 0)			GetCurrentDateTime(tmp);		else		{			tmp->tm_year = tm->tm_year;			tmp->tm_mon = tm->tm_mon;			tmp->tm_mday = tm->tm_mday;		}		tmp->tm_hour = tm->tm_hour;		tmp->tm_min = tm->tm_min;		tmp->tm_sec = tm->tm_sec;		*tzp = DetermineTimeZoneOffset(tmp, global_timezone);		tm->tm_isdst = tmp->tm_isdst;	}	return 0;}/* DecodeDate() * Decode date string which includes delimiters. * Return 0 if okay, a DTERR code if not. * * Insist on a complete set of fields. */static intDecodeDate(char *str, int fmask, int *tmask, struct pg_tm * tm){	fsec_t		fsec;	int			nf = 0;	int			i,				len;	int			dterr;	bool		haveTextMonth = FALSE;	int			bc = FALSE;	int			is2digits = FALSE;	int			type,				val,				dmask = 0;	char	   *field[MAXDATEFIELDS];	/* parse this string... */	while (*str != '\0' && nf < MAXDATEFIELDS)	{		/* skip field separators */		while (!isalnum((unsigned char) *str))			str++;		field[nf] = str;		if (isdigit((unsigned char) *str))		{			while (isdigit((unsigned char) *str))				str++;		}		else if (isalpha((unsigned char) *str))		{			while (isalpha((unsigned char) *str))				str++;		}		/* Just get rid of any non-digit, non-alpha characters... */		if (*str != '\0')			*str++ = '\0';		nf++;	}#if 0	/* don't allow too many fields */	if (nf > 3)		return DTERR_BAD_FORMAT;#endif	*tmask = 0;	/* look first for text fields, since that will be unambiguous month */	for (i = 0; i < nf; i++)	{		if (isalpha((unsigned char) *field[i]))		{			type = DecodeSpecial(i, field[i], &val);			if (type == IGNORE_DTF)				continue;			dmask = DTK_M(type);			switch (type)			{				case MONTH:					tm->tm_mon = val;					haveTextMonth = TRUE;					break;				case ADBC:					bc = (val == BC);					break;				default:					return DTERR_BAD_FORMAT;			}			if (fmask & dmask)				return DTERR_BAD_FORMAT;			fmask |= dmask;			*tmask |= dmask;			/* mark this field as being completed */			field[i] = NULL;		}	}	/* now pick up remaining numeric fields */	for (i = 0; i < nf; i++)	{		if (field[i] == NULL)			continue;		if ((len = strlen(field[i])) <= 0)			return DTERR_BAD_FORMAT;		dterr = DecodeNumber(len, field[i], haveTextMonth, fmask,							 &dmask, tm,							 &fsec, &is2digits);		if (dterr)			return dterr;		if (fmask & dmask)			return DTERR_BAD_FORMAT;		fmask |= dmask;		*tmask |= dmask;	}	if ((fmask & ~(DTK_M(DOY) | DTK_M(TZ))) != DTK_DATE_M)		return DTERR_BAD_FORMAT;	/* there is no year zero in AD/BC notation; i.e. "1 BC" == year 0 */	if (bc)	{		if (tm->tm_year > 0)			tm->tm_year = -(tm->tm_year - 1);		else			ereport(ERROR,					(errcode(ERRCODE_INVALID_DATETIME_FORMAT),					 errmsg("inconsistent use of year %04d and \"BC\"",							tm->tm_year)));	}	else if (is2digits)	{		if (tm->tm_year < 70)			tm->tm_year += 2000;		else if (tm->tm_year < 100)			tm->tm_year += 1900;	}	/* now that we have correct year, decode DOY */	if (fmask & DTK_M(DOY))	{		j2date(date2j(tm->tm_year, 1, 1) + tm->tm_yday - 1,			   &tm->tm_year, &tm->tm_mon, &tm->tm_mday);	}	/* check for valid month */	if (tm->tm_mon < 1 || tm->tm_mon > MONTHS_PER_YEAR)		return DTERR_MD_FIELD_OVERFLOW;	/* check for valid day */	if (tm->tm_mday < 1 || tm->tm_mday > 31)		return DTERR_MD_FIELD_OVERFLOW;	/* We don't want to hint about DateStyle for Feb 29 */	if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])		return DTERR_FIELD_OVERFLOW;	return 0;}/* DecodeTime() * Decode time string which includes delimiters. * Return 0 if okay, a DTERR code if not. * * Only check the lower limit on hours, since this same code *	can be used to represent time spans. */static intDecodeTime(char *str, int fmask, int *tmask, struct pg_tm * tm, fsec_t *fsec){	char	   *cp;	*tmask = DTK_TIME_M;	errno = 0;	tm->tm_hour = strtol(str, &cp, 10);	if (errno == ERANGE)		return DTERR_FIELD_OVERFLOW;	if (*cp != ':')		return DTERR_BAD_FORMAT;	str = cp + 1;	errno = 0;	tm->tm_min = strtol(str, &c

⌨️ 快捷键说明

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