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

📄 timestamp.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
									 IntervalOffsets[precision]) /									IntervalScales[precision]) *								   IntervalScales[precision]);			}#else			interval->time = rint(((double) interval->time) *								  IntervalScales[precision]) /				IntervalScales[precision];#endif		}	}	return;}/* EncodeSpecialTimestamp() * Convert reserved timestamp data type to string. */static intEncodeSpecialTimestamp(Timestamp dt, char *str){	if (TIMESTAMP_IS_NOBEGIN(dt))		strcpy(str, EARLY);	else if (TIMESTAMP_IS_NOEND(dt))		strcpy(str, LATE);	else		return FALSE;	return TRUE;}	/* EncodeSpecialTimestamp() */Datumnow(PG_FUNCTION_ARGS){	PG_RETURN_TIMESTAMPTZ(GetCurrentTransactionStartTimestamp());}Datumstatement_timestamp(PG_FUNCTION_ARGS){	PG_RETURN_TIMESTAMPTZ(GetCurrentStatementStartTimestamp());}Datumclock_timestamp(PG_FUNCTION_ARGS){	PG_RETURN_TIMESTAMPTZ(GetCurrentTimestamp());}Datumpgsql_postmaster_start_time(PG_FUNCTION_ARGS){	PG_RETURN_TIMESTAMPTZ(PgStartTime);}/* * GetCurrentTimestamp -- get the current operating system time * * Result is in the form of a TimestampTz value, and is expressed to the * full precision of the gettimeofday() syscall */TimestampTzGetCurrentTimestamp(void){	TimestampTz result;	struct timeval tp;	gettimeofday(&tp, NULL);	result = (TimestampTz) tp.tv_sec -		((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);#ifdef HAVE_INT64_TIMESTAMP	result = (result * USECS_PER_SEC) + tp.tv_usec;#else	result = result + (tp.tv_usec / 1000000.0);#endif	return result;}/* * TimestampDifference -- convert the difference between two timestamps *		into integer seconds and microseconds * * Both inputs must be ordinary finite timestamps (in current usage, * they'll be results from GetCurrentTimestamp()). * * We expect start_time <= stop_time.  If not, we return zeroes; for current * callers there is no need to be tense about which way division rounds on * negative inputs. */voidTimestampDifference(TimestampTz start_time, TimestampTz stop_time,					long *secs, int *microsecs){	TimestampTz diff = stop_time - start_time;	if (diff <= 0)	{		*secs = 0;		*microsecs = 0;	}	else	{#ifdef HAVE_INT64_TIMESTAMP		*secs = (long) (diff / USECS_PER_SEC);		*microsecs = (int) (diff % USECS_PER_SEC);#else		*secs = (long) diff;		*microsecs = (int) ((diff - *secs) * 1000000.0);#endif	}}/* * TimestampDifferenceExceeds -- report whether the difference between two *		timestamps is >= a threshold (expressed in milliseconds) * * Both inputs must be ordinary finite timestamps (in current usage, * they'll be results from GetCurrentTimestamp()). */boolTimestampDifferenceExceeds(TimestampTz start_time,						   TimestampTz stop_time,						   int msec){	TimestampTz diff = stop_time - start_time;#ifdef HAVE_INT64_TIMESTAMP	return (diff >= msec * INT64CONST(1000));#else	return (diff * 1000.0 >= msec);#endif}/* * Convert a time_t to TimestampTz. * * We do not use time_t internally in Postgres, but this is provided for use * by functions that need to interpret, say, a stat(2) result. */TimestampTztime_t_to_timestamptz(time_t tm){	TimestampTz result;	result = (TimestampTz) tm -		((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);#ifdef HAVE_INT64_TIMESTAMP	result *= USECS_PER_SEC;#endif	return result;}/* * Convert a TimestampTz to time_t. * * This too is just marginally useful, but some places need it. */time_ttimestamptz_to_time_t(TimestampTz t){	time_t		result;#ifdef HAVE_INT64_TIMESTAMP	result = (time_t) (t / USECS_PER_SEC +				 ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY));#else	result = (time_t) (t +				 ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY));#endif	return result;}/* * Produce a C-string representation of a TimestampTz. * * This is mostly for use in emitting messages.  The primary difference * from timestamptz_out is that we force the output format to ISO.	Note * also that the result is in a static buffer, not pstrdup'd. */const char *timestamptz_to_str(TimestampTz t){	static char buf[MAXDATELEN + 1];	int			tz;	struct pg_tm tt,			   *tm = &tt;	fsec_t		fsec;	char	   *tzn;	if (TIMESTAMP_NOT_FINITE(t))		EncodeSpecialTimestamp(t, buf);	else if (timestamp2tm(t, &tz, tm, &fsec, &tzn, NULL) == 0)		EncodeDateTime(tm, fsec, &tz, &tzn, USE_ISO_DATES, buf);	else		strlcpy(buf, "(timestamp out of range)", sizeof(buf));	return buf;}voiddt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec){#ifdef HAVE_INT64_TIMESTAMP	int64		time;#else	double		time;#endif	time = jd;#ifdef HAVE_INT64_TIMESTAMP	*hour = time / USECS_PER_HOUR;	time -= (*hour) * USECS_PER_HOUR;	*min = time / USECS_PER_MINUTE;	time -= (*min) * USECS_PER_MINUTE;	*sec = time / USECS_PER_SEC;	*fsec = time - (*sec * USECS_PER_SEC);#else	*hour = time / SECS_PER_HOUR;	time -= (*hour) * SECS_PER_HOUR;	*min = time / SECS_PER_MINUTE;	time -= (*min) * SECS_PER_MINUTE;	*sec = time;	*fsec = time - *sec;#endif}	/* dt2time() *//* * timestamp2tm() - Convert timestamp data type to POSIX time structure. * * Note that year is _not_ 1900-based, but is an explicit full value. * Also, month is one-based, _not_ zero-based. * Returns: *	 0 on success *	-1 on out of range * * If attimezone is NULL, the global timezone (including possibly brute forced * timezone) will be used. */inttimestamp2tm(Timestamp dt, int *tzp, struct pg_tm * tm, fsec_t *fsec, char **tzn, pg_tz *attimezone){	Timestamp	date;	Timestamp	time;	pg_time_t	utime;	/*	 * If HasCTZSet is true then we have a brute force time zone specified. Go	 * ahead and rotate to the local time zone since we will later bypass any	 * calls which adjust the tm fields.	 */	if (attimezone == NULL && HasCTZSet && tzp != NULL)	{#ifdef HAVE_INT64_TIMESTAMP		dt -= CTimeZone * USECS_PER_SEC;#else		dt -= CTimeZone;#endif	}#ifdef HAVE_INT64_TIMESTAMP	time = dt;	TMODULO(time, date, USECS_PER_DAY);	if (time < INT64CONST(0))	{		time += USECS_PER_DAY;		date -= 1;	}	/* add offset to go from J2000 back to standard Julian date */	date += POSTGRES_EPOCH_JDATE;	/* Julian day routine does not work for negative Julian days */	if (date < 0 || date > (Timestamp) INT_MAX)		return -1;	j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);	dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);#else	time = dt;	TMODULO(time, date, (double) SECS_PER_DAY);	if (time < 0)	{		time += SECS_PER_DAY;		date -= 1;	}	/* add offset to go from J2000 back to standard Julian date */	date += POSTGRES_EPOCH_JDATE;recalc_d:	/* Julian day routine does not work for negative Julian days */	if (date < 0 || date > (Timestamp) INT_MAX)		return -1;	j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);recalc_t:	dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);	*fsec = TSROUND(*fsec);	/* roundoff may need to propagate to higher-order fields */	if (*fsec >= 1.0)	{		time = ceil(time);		if (time >= (double) SECS_PER_DAY)		{			time = 0;			date += 1;			goto recalc_d;		}		goto recalc_t;	}#endif	/* Done if no TZ conversion wanted */	if (tzp == NULL)	{		tm->tm_isdst = -1;		tm->tm_gmtoff = 0;		tm->tm_zone = NULL;		if (tzn != NULL)			*tzn = NULL;		return 0;	}	/*	 * We have a brute force time zone per SQL99? Then use it without change	 * since we have already rotated to the time zone.	 */	if (attimezone == NULL && HasCTZSet)	{		*tzp = CTimeZone;		tm->tm_isdst = 0;		tm->tm_gmtoff = CTimeZone;		tm->tm_zone = NULL;		if (tzn != NULL)			*tzn = NULL;		return 0;	}	/*	 * If the time falls within the range of pg_time_t, use pg_localtime() to	 * rotate to the local time zone.	 *	 * First, convert to an integral timestamp, avoiding possibly	 * platform-specific roundoff-in-wrong-direction errors, and adjust to	 * Unix epoch.	Then see if we can convert to pg_time_t without loss. This	 * coding avoids hardwiring any assumptions about the width of pg_time_t,	 * so it should behave sanely on machines without int64.	 */#ifdef HAVE_INT64_TIMESTAMP	dt = (dt - *fsec) / USECS_PER_SEC +		(POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY;#else	dt = rint(dt - *fsec +			  (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);#endif	utime = (pg_time_t) dt;	if ((Timestamp) utime == dt)	{		struct pg_tm *tx = pg_localtime(&utime,								 attimezone ? attimezone : session_timezone);		tm->tm_year = tx->tm_year + 1900;		tm->tm_mon = tx->tm_mon + 1;		tm->tm_mday = tx->tm_mday;		tm->tm_hour = tx->tm_hour;		tm->tm_min = tx->tm_min;		tm->tm_sec = tx->tm_sec;		tm->tm_isdst = tx->tm_isdst;		tm->tm_gmtoff = tx->tm_gmtoff;		tm->tm_zone = tx->tm_zone;		*tzp = -tm->tm_gmtoff;		if (tzn != NULL)			*tzn = (char *) tm->tm_zone;	}	else	{		/*		 * When out of range of pg_time_t, treat as GMT		 */		*tzp = 0;		/* Mark this as *no* time zone available */		tm->tm_isdst = -1;		tm->tm_gmtoff = 0;		tm->tm_zone = NULL;		if (tzn != NULL)			*tzn = NULL;	}	return 0;}/* tm2timestamp() * Convert a tm structure to a timestamp data type. * Note that year is _not_ 1900-based, but is an explicit full value. * Also, month is one-based, _not_ zero-based. * * Returns -1 on failure (value out of range). */inttm2timestamp(struct pg_tm * tm, fsec_t fsec, int *tzp, Timestamp *result){#ifdef HAVE_INT64_TIMESTAMP	int			date;	int64		time;#else	double		date,				time;#endif	/* Julian day routines are not correct for negative Julian days */	if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))	{		*result = 0;			/* keep compiler quiet */		return -1;	}	date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;	time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);#ifdef HAVE_INT64_TIMESTAMP	*result = date * USECS_PER_DAY + time;	/* check for major overflow */	if ((*result - time) / USECS_PER_DAY != date)	{		*result = 0;			/* keep compiler quiet */		return -1;	}	/* check for just-barely overflow (okay except time-of-day wraps) */	if ((*result < 0 && date >= 0) ||		(*result >= 0 && date < 0))	{		*result = 0;			/* keep compiler quiet */		return -1;	}#else	*result = date * SECS_PER_DAY + time;#endif	if (tzp != NULL)		*result = dt2local(*result, -(*tzp));	return 0;}/* interval2tm() * Convert a interval data type to a tm structure. */intinterval2tm(Interval span, struct pg_tm * tm, fsec_t *fsec){#ifdef HAVE_INT64_TIMESTAMP	int64		time;	int64		tfrac;#else	double		time;	double		tfrac;#endif	tm->tm_year = span.month / MONTHS_PER_YEAR;	tm->tm_mon = span.month % MONTHS_PER_YEAR;	tm->tm_mday = span.day;	time = span.time;#ifdef HAVE_INT64_TIMESTAMP	tfrac = time / USECS_PER_HOUR;	time -= tfrac * USECS_PER_HOUR;	tm->tm_hour = tfrac;		/* could overflow ... */	tfrac = time / USECS_PER_MINUTE;	time -= tfrac * USECS_PER_MINUTE;	tm->tm_min = tfrac;	tfrac = time / USECS_PER_SEC;	*fsec = time - (tfrac * USECS_PER_SEC);	tm->tm_sec = tfrac;#elserecalc:	TMODULO(time, tfrac, (double) SECS_PER_HOUR);	tm->tm_hour = tfrac;		/* could overflow ... */	TMODULO(time, tfrac, (double) SECS_PER_MINUTE);	tm->tm_min = tfrac;	TMODULO(time, tfrac, 1.0);	tm->tm_sec = tfrac;	time = TSROUND(time);	/* roundoff may need to propagate to higher-order fields */	if (time >= 1.0)	{		time = ceil(span.time);		goto recalc;	}	*fsec = time;#endif	return 0;}inttm2interval(struct pg_tm * tm, fsec_t fsec, Interval *span){	span->month = tm->tm_year * MONTHS_PER_YEAR + tm->tm_mon;	span->day = tm->tm_mday;#ifdef HAVE_INT64_TIMESTAMP	span->time = (((((tm->tm_hour * INT64CONST(60)) +					 tm->tm_min) * INT64CONST(60)) +				   tm->tm_sec) * USECS_PER_SEC) + fsec;#else	span->time = (((tm->tm_hour * (double) MINS_PER_HOUR) +				   tm->tm_min) * (double) SECS_PER_MINUTE) +		tm->tm_sec + fsec;#endif	return 0;}#ifdef HAVE_INT64_TIMESTAMPstatic int64time2t(const int hour, const int min, const int sec, const fsec_t fsec){	return (((((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec) * USECS_PER_SEC) + fsec;}	/* time2t() */#elsestatic doubletime2t(const int hour, const int min, const int sec, const fsec_t fsec){	return (((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec + fsec;}	/* time2t() */#endifstatic Timestampdt2local(Timestamp dt, int tz){#ifdef HAVE_INT64_TIMESTAMP	dt -= (tz * USECS_PER_SEC);#else	dt -= tz;#endif	return dt;}	/* dt2local() *//***************************************************************************** *	 PUBLIC ROUTINES														 * *****************************************************************************/Datumtimestamp_finite(PG_FUNCTION_ARGS){	Timestamp	timestamp = PG_GETARG_TIMESTAMP(0);

⌨️ 快捷键说明

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