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

📄 dt_common.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
char	   *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};char	   *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", NULL};char	   *pgtypes_date_weekdays_short[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL};char	   *pgtypes_date_months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", NULL};static datetkn *datebsearch(char *key, datetkn *base, unsigned int nel){	datetkn    *last = base + nel - 1,			   *position;	int			result;	while (last >= base)	{		position = base + ((last - base) >> 1);		result = key[0] - position->token[0];		if (result == 0)		{			result = strncmp(key, position->token, TOKMAXLEN);			if (result == 0)				return position;		}		if (result < 0)			last = position - 1;		else			base = position + 1;	}	return NULL;}/* DecodeUnits() * Decode text string using lookup table. * This routine supports time interval decoding. */intDecodeUnits(int field, char *lowtoken, int *val){	int			type;	datetkn    *tp;	if (deltacache[field] != NULL &&		strncmp(lowtoken, deltacache[field]->token, TOKMAXLEN) == 0)		tp = deltacache[field];	else		tp = datebsearch(lowtoken, deltatktbl, szdeltatktbl);	deltacache[field] = tp;	if (tp == NULL)	{		type = UNKNOWN_FIELD;		*val = 0;	}	else	{		type = tp->type;		if (type == TZ || type == DTZ)			*val = FROMVAL(tp);		else			*val = tp->value;	}	return type;}	/* DecodeUnits() *//* * Calendar time to Julian date conversions. * Julian date is commonly used in astronomical applications, *	since it is numerically accurate and computationally simple. * The algorithms here will accurately convert between Julian day *	and calendar date for all non-negative Julian days *	(i.e. from Nov 24, -4713 on). * * These routines will be used by other date/time packages * - thomas 97/02/25 * * Rewritten to eliminate overflow problems. This now allows the * routines to work correctly for all Julian day counts from * 0 to 2147483647	(Nov 24, -4713 to Jun 3, 5874898) assuming * a 32-bit integer. Longer types should also work to the limits * of their precision. */intdate2j(int y, int m, int d){	int			julian;	int			century;	if (m > 2)	{		m += 1;		y += 4800;	}	else	{		m += 13;		y += 4799;	}	century = y / 100;	julian = y * 365 - 32167;	julian += y / 4 - century + century / 4;	julian += 7834 * m / 256 + d;	return julian;}	/* date2j() */voidj2date(int jd, int *year, int *month, int *day){	unsigned int julian;	unsigned int quad;	unsigned int extra;	int			y;	julian = jd;	julian += 32044;	quad = julian / 146097;	extra = (julian - quad * 146097) * 4 + 3;	julian += 60 + quad * 3 + extra / 146097;	quad = julian / 1461;	julian -= quad * 1461;	y = julian * 4 / 1461;	julian = ((y != 0) ? (julian + 305) % 365 : (julian + 306) % 366) + 123;	y += quad * 4;	*year = y - 4800;	quad = julian * 2141 / 65536;	*day = julian - 7834 * quad / 256;	*month = (quad + 10) % 12 + 1;	return;}	/* j2date() *//* DecodeSpecial() * Decode text string using lookup table. * Implement a cache lookup since it is likely that dates *	will be related in format. */static intDecodeSpecial(int field, char *lowtoken, int *val){	int			type;	datetkn    *tp;	if (datecache[field] != NULL &&		strncmp(lowtoken, datecache[field]->token, TOKMAXLEN) == 0)		tp = datecache[field];	else	{		tp = NULL;		if (!tp)			tp = datebsearch(lowtoken, datetktbl, szdatetktbl);	}	datecache[field] = tp;	if (tp == NULL)	{		type = UNKNOWN_FIELD;		*val = 0;	}	else	{		type = tp->type;		switch (type)		{			case TZ:			case DTZ:			case DTZMOD:				*val = FROMVAL(tp);				break;			default:				*val = tp->value;				break;		}	}	return type;}	/* DecodeSpecial() *//* EncodeDateOnly() * Encode date as local time. */intEncodeDateOnly(struct tm * tm, int style, char *str, bool EuroDates){	if (tm->tm_mon < 1 || tm->tm_mon > MONTHS_PER_YEAR)		return -1;	switch (style)	{		case USE_ISO_DATES:			/* compatible with ISO date formats */			if (tm->tm_year > 0)				sprintf(str, "%04d-%02d-%02d",						tm->tm_year, tm->tm_mon, tm->tm_mday);			else				sprintf(str, "%04d-%02d-%02d %s",						-(tm->tm_year - 1), tm->tm_mon, tm->tm_mday, "BC");			break;		case USE_SQL_DATES:			/* compatible with Oracle/Ingres date formats */			if (EuroDates)				sprintf(str, "%02d/%02d", tm->tm_mday, tm->tm_mon);			else				sprintf(str, "%02d/%02d", tm->tm_mon, tm->tm_mday);			if (tm->tm_year > 0)				sprintf(str + 5, "/%04d", tm->tm_year);			else				sprintf(str + 5, "/%04d %s", -(tm->tm_year - 1), "BC");			break;		case USE_GERMAN_DATES:			/* German-style date format */			sprintf(str, "%02d.%02d", tm->tm_mday, tm->tm_mon);			if (tm->tm_year > 0)				sprintf(str + 5, ".%04d", tm->tm_year);			else				sprintf(str + 5, ".%04d %s", -(tm->tm_year - 1), "BC");			break;		case USE_POSTGRES_DATES:		default:			/* traditional date-only style for Postgres */			if (EuroDates)				sprintf(str, "%02d-%02d", tm->tm_mday, tm->tm_mon);			else				sprintf(str, "%02d-%02d", tm->tm_mon, tm->tm_mday);			if (tm->tm_year > 0)				sprintf(str + 5, "-%04d", tm->tm_year);			else				sprintf(str + 5, "-%04d %s", -(tm->tm_year - 1), "BC");			break;	}	return TRUE;}	/* EncodeDateOnly() */static voidTrimTrailingZeros(char *str){	int			len = strlen(str);	/* chop off trailing zeros... but leave at least 2 fractional digits */	while (*(str + len - 1) == '0' && *(str + len - 3) != '.')	{		len--;		*(str + len) = '\0';	}}/* EncodeDateTime() * Encode date and time interpreted as local time. * Support several date styles: *	Postgres - day mon hh:mm:ss yyyy tz *	SQL - mm/dd/yyyy hh:mm:ss.ss tz *	ISO - yyyy-mm-dd hh:mm:ss+/-tz *	German - dd.mm.yyyy hh:mm:ss tz * Variants (affects order of month and day for Postgres and SQL styles): *	US - mm/dd/yyyy *	European - dd/mm/yyyy */intEncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str, bool EuroDates){	int			day,				hour,				min;	switch (style)	{		case USE_ISO_DATES:			/* Compatible with ISO-8601 date formats */			sprintf(str, "%04d-%02d-%02d %02d:%02d",					(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),					tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);			/*			 * Print fractional seconds if any.  The field widths here should			 * be at least equal to MAX_TIMESTAMP_PRECISION.			 *			 * In float mode, don't print fractional seconds before 1 AD,			 * since it's unlikely there's any precision left ...			 */#ifdef HAVE_INT64_TIMESTAMP			if (fsec != 0)			{				sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec);#else			if ((fsec != 0) && (tm->tm_year > 0))			{				sprintf(str + strlen(str), ":%09.6f", tm->tm_sec + fsec);#endif				TrimTrailingZeros(str);			}			else				sprintf(str + strlen(str), ":%02d", tm->tm_sec);			if (tm->tm_year <= 0)				sprintf(str + strlen(str), " BC");			/*			 * tzp == NULL indicates that we don't want *any* time zone info			 * in the output string. *tzn != NULL indicates that we have alpha			 * time zone info available. tm_isdst != -1 indicates that we have			 * a valid time zone translation.			 */			if (tzp != NULL && tm->tm_isdst >= 0)			{				hour = -(*tzp / SECS_PER_HOUR);				min = (abs(*tzp) / MINS_PER_HOUR) % MINS_PER_HOUR;				sprintf(str + strlen(str), (min != 0) ? "%+03d:%02d" : "%+03d", hour, min);			}			break;		case USE_SQL_DATES:			/* Compatible with Oracle/Ingres date formats */			if (EuroDates)				sprintf(str, "%02d/%02d", tm->tm_mday, tm->tm_mon);			else				sprintf(str, "%02d/%02d", tm->tm_mon, tm->tm_mday);			sprintf(str + 5, "/%04d %02d:%02d",					(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),					tm->tm_hour, tm->tm_min);			/*			 * Print fractional seconds if any.  The field widths here should			 * be at least equal to MAX_TIMESTAMP_PRECISION.			 *			 * In float mode, don't print fractional seconds before 1 AD,			 * since it's unlikely there's any precision left ...			 */#ifdef HAVE_INT64_TIMESTAMP			if (fsec != 0)			{				sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec);#else			if (fsec != 0 && tm->tm_year > 0)			{				sprintf(str + strlen(str), ":%09.6f", tm->tm_sec + fsec);#endif				TrimTrailingZeros(str);			}			else				sprintf(str + strlen(str), ":%02d", tm->tm_sec);			if (tm->tm_year <= 0)				sprintf(str + strlen(str), " BC");			if (tzp != NULL && tm->tm_isdst >= 0)			{				if (*tzn != NULL)					sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);				else				{					hour = -(*tzp / SECS_PER_HOUR);					min = (abs(*tzp) / MINS_PER_HOUR) % MINS_PER_HOUR;					sprintf(str + strlen(str), (min != 0) ? "%+03d:%02d" : "%+03d", hour, min);				}			}			break;		case USE_GERMAN_DATES:			/* German variant on European style */			sprintf(str, "%02d.%02d", tm->tm_mday, tm->tm_mon);			sprintf(str + 5, ".%04d %02d:%02d",					(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),					tm->tm_hour, tm->tm_min);			/*			 * Print fractional seconds if any.  The field widths here should			 * be at least equal to MAX_TIMESTAMP_PRECISION.			 *			 * In float mode, don't print fractional seconds before 1 AD,			 * since it's unlikely there's any precision left ...			 */#ifdef HAVE_INT64_TIMESTAMP			if (fsec != 0)			{				sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec);#else			if (fsec != 0 && tm->tm_year > 0)			{				sprintf(str + strlen(str), ":%09.6f", tm->tm_sec + fsec);#endif				TrimTrailingZeros(str);			}			else				sprintf(str + strlen(str), ":%02d", tm->tm_sec);			if (tm->tm_year <= 0)				sprintf(str + strlen(str), " BC");			if (tzp != NULL && tm->tm_isdst >= 0)			{				if (*tzn != NULL)					sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);				else				{					hour = -(*tzp / SECS_PER_HOUR);					min = (abs(*tzp) / MINS_PER_HOUR) % MINS_PER_HOUR;					sprintf(str + strlen(str), (min != 0) ? "%+03d:%02d" : "%+03d", hour, min);				}			}			break;		case USE_POSTGRES_DATES:		default:			/* Backward-compatible with traditional Postgres abstime dates */			day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);			tm->tm_wday = (int) ((day + date2j(2000, 1, 1) + 1) % 7);			strncpy(str, days[tm->tm_wday], 3);			strcpy(str + 3, " ");			if (EuroDates)				sprintf(str + 4, "%02d %3s", tm->tm_mday, months[tm->tm_mon - 1]);			else				sprintf(str + 4, "%3s %02d", months[tm->tm_mon - 1], tm->tm_mday);			sprintf(str + 10, " %02d:%02d", tm->tm_hour, tm->tm_min);			/*			 * Print fractional seconds if any.  The field widths here should			 * be at least equal to MAX_TIMESTAMP_PRECISION.			 *			 * In float mode, don't print fractional seconds before 1 AD,			 * since it's unlikely there's any precision left ...			 */#ifdef HAVE_INT64_TIMESTAMP			if (fsec != 0)			{				sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec);#else			if (fsec != 0 && tm->tm_year > 0)			{				sprintf(str + strlen(str), ":%09.6f", tm->tm_sec + fsec);#endif				TrimTrailingZeros(str);			}			else				sprintf(str + strlen(str), ":%02d", tm->tm_sec);			sprintf(str + strlen(str), " %04d",					(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1));			if (tm->tm_year <= 0)				sprintf(str + strlen(str), " BC");			if (tzp != NULL && tm->tm_isdst >= 0)			{				if (*tzn != NULL)					sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);				else				{					/*					 * We have a time zone, but no string version. Use the					 * numeric form, but be sure to include a leading space to					 * avoid formatting something which would be rejected by					 * the date/time parser later. - thomas 2001-10-19					 */					hour = -(*tzp / SECS_PER_HOUR);					min = (abs(*tzp) / MINS_PER_HOUR) % MINS_PER_HOUR;					sprintf(str + strlen(str), (min != 0) ? " %+03d:%02d" : " %+03d", hour, min);				}			}			break;	}	return TRUE;}	/* EncodeDateTime() */voidGetEpochTime(struct tm * tm){	struct tm  *t0;	time_t		epoch = 0;	t0 = gmtime(&epoch);	tm->tm_year = t0->tm_year;	tm->tm_mon = t0->tm_mon;	tm->tm_mday = t0->tm_mday;	tm->tm_hour = t0->tm_hour;	tm->tm_min = t0->tm_min;	tm->tm_sec = t0->tm_sec;	if (tm->tm_year < 1900)		tm->tm_year += 1900;	tm->tm_mon++;	return;}	/* GetEpochTime() */

⌨️ 快捷键说明

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