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

📄 date.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * date.c *	  Utilities for the built-in type "AbsoluteTime" (defined in nabstime). *	  Functions for the built-in type "RelativeTime". *	  Functions for the built-in type "TimeInterval". * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.32.2.1 1999/08/02 05:24:51 scrappy Exp $ * * NOTES *	 This code is actually (almost) unused. *	 It needs to be integrated with Time and struct trange. * * XXX	This code needs to be rewritten to work with the "new" definitions * XXX	in h/tim.h.  Look for int32's, int, long, etc. in the code.  The * XXX	definitions in h/tim.h may need to be rethought also. * * XXX	This code has been cleaned up some - avi 07/07/93 * *------------------------------------------------------------------------- */#include <ctype.h>#include <time.h>#include <sys/time.h>#include <sys/types.h>#include "postgres.h"#ifdef HAVE_FLOAT_H#include <float.h>#endif#ifdef HAVE_LIMITS_H#include <limits.h>#endif#include "access/xact.h"#include "miscadmin.h"#include "utils/builtins.h"#include "utils/dt.h"#define INVALID_RELTIME_STR		"Undefined RelTime"#define INVALID_RELTIME_STR_LEN (sizeof(INVALID_RELTIME_STR)-1)#define RELTIME_LABEL			'@'#define RELTIME_PAST			"ago"#define DIRMAXLEN				(sizeof(RELTIME_PAST)-1)/* *	Unix epoch is Jan  1 00:00:00 1970.  Postgres knows about times *	sixty-eight years on either side of that. */#define IsSpace(C)				((C) == ' ')#define T_INTERVAL_INVAL   0	/* data represents no valid interval */#define T_INTERVAL_VALID   1	/* data represents a valid interval *//* * ['Mon May 10 23:59:12 1943 PST' 'Sun Jan 14 03:14:21 1973 PST'] * 0		1		  2			3		  4			5		  6 * 1234567890123456789012345678901234567890123456789012345678901234 * * we allocate some extra -- timezones are usually 3 characters but * this is not in the POSIX standard... */#define T_INTERVAL_LEN					80#define INVALID_INTERVAL_STR			"Undefined Range"#define INVALID_INTERVAL_STR_LEN		(sizeof(INVALID_INTERVAL_STR)-1)#define ABSTIMEMIN(t1, t2) abstimele((t1),(t2)) ? (t1) : (t2)#define ABSTIMEMAX(t1, t2) abstimelt((t1),(t2)) ? (t2) : (t1)#ifdef NOT_USEDstatic char *unit_tab[] = {	"second", "seconds", "minute", "minutes",	"hour", "hours", "day", "days", "week", "weeks","month", "months", "year", "years"};#define UNITMAXLEN 7			/* max length of a unit name */#define NUNITS 14				/* number of different units *//* table of seconds per unit (month = 30 days, year = 365 days)  */static int	sec_tab[] = {	1, 1, 60, 60,	3600, 3600, 86400, 86400, 604800, 604800,2592000, 2592000, 31536000, 31536000};#endif/* * Function prototypes -- internal to this file only */static void reltime2tm(RelativeTime time, struct tm * tm);#ifdef NOT_USEDstatic int	correct_unit(char *unit, int *unptr);static int	correct_dir(char *direction, int *signptr);#endifstatic int istinterval(char *i_string,			AbsoluteTime *i_start,			AbsoluteTime *i_end);/***************************************************************************** *	 USER I/O ROUTINES														 * *****************************************************************************//* *		reltimein		- converts a reltime string in an internal format */RelativeTimereltimein(char *str){	RelativeTime result;	struct tm	tt,			   *tm = &tt;	double		fsec;	int			dtype;	char	   *field[MAXDATEFIELDS];	int			nf,				ftype[MAXDATEFIELDS];	char		lowstr[MAXDATELEN + 1];	if (!PointerIsValid(str))		elog(ERROR, "Bad (null) date external representation", NULL);	if (strlen(str) > MAXDATELEN)		elog(ERROR, "Bad (length) reltime external representation '%s'", str);	if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)		|| (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0))		elog(ERROR, "Bad reltime external representation '%s'", str);#ifdef DATEDEBUG	printf("reltimein- %d fields are type %d (DTK_DATE=%d)\n", nf, dtype, DTK_DATE);#endif	switch (dtype)	{		case DTK_DELTA:			result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec);			result += (((tm->tm_year * 365) + (tm->tm_mon * 30) + tm->tm_mday) * (24 * 60 * 60));			return result;		default:			return INVALID_RELTIME;	}	elog(ERROR, "Bad reltime (internal coding error) '%s'", str);	return INVALID_RELTIME;}	/* reltimein() *//* *		reltimeout		- converts the internal format to a reltime string */char *reltimeout(RelativeTime time){	char	   *result;	struct tm	tt,			   *tm = &tt;	char		buf[MAXDATELEN + 1];	if (time == INVALID_RELTIME)	{		strcpy(buf, INVALID_RELTIME_STR);	}	else	{		reltime2tm(time, tm);		EncodeTimeSpan(tm, 0, DateStyle, buf);	}	result = palloc(strlen(buf) + 1);	strcpy(result, buf);	return result;}	/* reltimeout() */#define TMODULO(t,q,u) \do { \	q = (t / u); \	if (q != 0) t -= (q * u); \} while(0)static voidreltime2tm(RelativeTime time, struct tm * tm){	TMODULO(time, tm->tm_year, 31536000);	TMODULO(time, tm->tm_mon, 2592000);	TMODULO(time, tm->tm_mday, 86400);	TMODULO(time, tm->tm_hour, 3600);	TMODULO(time, tm->tm_min, 60);	TMODULO(time, tm->tm_sec, 1);	return;}	/* reltime2tm() */#ifdef NOT_USEDintdummyfunc(){	char	   *timestring;	long		quantity;	int			i;	int			unitnr;	timestring = (char *) palloc(Max(strlen(INVALID_RELTIME_STR),									 UNITMAXLEN) + 1);	if (timevalue == INVALID_RELTIME)	{		strcpy(timestring, INVALID_RELTIME_STR);		return timestring;	}	if (timevalue == 0)		i = 1;					/* unit = 'seconds' */	else		for (i = 12; i >= 0; i = i - 2)			if ((timevalue % sec_tab[i]) == 0)				break;			/* appropriate unit found */	unitnr = i;	quantity = (timevalue / sec_tab[unitnr]);	if (quantity > 1 || quantity < -1)		unitnr++;				/* adjust index for PLURAL of unit */	if (quantity >= 0)		sprintf(timestring, "%c %lu %s", RELTIME_LABEL,				quantity, unit_tab[unitnr]);	else		sprintf(timestring, "%c %lu %s %s", RELTIME_LABEL,				(quantity * -1), unit_tab[unitnr], RELTIME_PAST);	return timestring;}#endif/* *		tintervalin		- converts an interval string to an internal format */TimeIntervaltintervalin(char *intervalstr){	int			error;	AbsoluteTime i_start,				i_end,				t1,				t2;	TimeInterval interval;	interval = (TimeInterval) palloc(sizeof(TimeIntervalData));	error = istinterval(intervalstr, &t1, &t2);	if (error == 0)		interval->status = T_INTERVAL_INVAL;	if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)		interval->status = T_INTERVAL_INVAL;	/* undefined  */	else	{		i_start = ABSTIMEMIN(t1, t2);		i_end = ABSTIMEMAX(t1, t2);		interval->data[0] = i_start;		interval->data[1] = i_end;		interval->status = T_INTERVAL_VALID;	}	return interval;}/* *		tintervalout	- converts an internal interval format to a string * */char *tintervalout(TimeInterval interval){	char	   *i_str,			   *p;	i_str = (char *) palloc(T_INTERVAL_LEN);	/* ['...' '...'] */	strcpy(i_str, "[\"");	if (interval->status == T_INTERVAL_INVAL)		strcat(i_str, INVALID_INTERVAL_STR);	else	{		p = nabstimeout(interval->data[0]);		strcat(i_str, p);		pfree(p);		strcat(i_str, "\" \"");		p = nabstimeout(interval->data[1]);		strcat(i_str, p);		pfree(p);	}	strcat(i_str, "\"]\0");	return i_str;}/***************************************************************************** *	 PUBLIC ROUTINES														 * *****************************************************************************/RelativeTimetimespan_reltime(TimeSpan *timespan){	RelativeTime time;	int			year,				month;	double		span;	if (!PointerIsValid(timespan))		time = INVALID_RELTIME;	if (TIMESPAN_IS_INVALID(*timespan))	{		time = INVALID_RELTIME;	}	else	{		if (timespan->month == 0)		{			year = 0;			month = 0;		}		else if (abs(timespan->month) >= 12)		{			year = (timespan->month / 12);			month = (timespan->month % 12);		}		else		{			year = 0;			month = timespan->month;		}		span = (((((double) 365 * year) + ((double) 30 * month)) * 86400) + timespan->time);#ifdef DATEDEBUG		printf("timespan_reltime- convert m%d s%f to %f [%d %d]\n",			   timespan->month, timespan->time, span, INT_MIN, INT_MAX);#endif		time = (((span > INT_MIN) && (span < INT_MAX)) ? span : INVALID_RELTIME);	}	return time;}	/* timespan_reltime() */TimeSpan   *reltime_timespan(RelativeTime reltime){	TimeSpan   *result;	int			year,				month;	if (!PointerIsValid(result = palloc(sizeof(TimeSpan))))		elog(ERROR, "Memory allocation failed, can't convert reltime to timespan", NULL);	switch (reltime)	{		case INVALID_RELTIME:			TIMESPAN_INVALID(*result);			break;		default:			TMODULO(reltime, year, 31536000);			TMODULO(reltime, month, 2592000);			result->time = reltime;			result->month = ((12 * year) + month);	}	return result;}	/* reltime_timespan() *//* *		mktinterval		- creates a time interval with endpoints t1 and t2 */TimeIntervalmktinterval(AbsoluteTime t1, AbsoluteTime t2){	AbsoluteTime tstart = ABSTIMEMIN(t1, t2),				tend = ABSTIMEMAX(t1, t2);	TimeInterval interval;	interval = (TimeInterval) palloc(sizeof(TimeIntervalData));	if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)		interval->status = T_INTERVAL_INVAL;	else	{		interval->status = T_INTERVAL_VALID;		interval->data[0] = tstart;		interval->data[1] = tend;	}	return interval;}/* *		timepl, timemi and abstimemi use the formula *				abstime + reltime = abstime *		so		abstime - reltime = abstime *		and		abstime - abstime = reltime *//* *		timepl			- returns the value of (abstime t1 + relime t2) */AbsoluteTimetimepl(AbsoluteTime t1, RelativeTime t2){	if (t1 == CURRENT_ABSTIME)		t1 = GetCurrentTransactionStartTime();	if (AbsoluteTimeIsReal(t1) &&		RelativeTimeIsValid(t2) &&		((t2 > 0) ? (t1 < NOEND_ABSTIME - t2)		 : (t1 > NOSTART_ABSTIME - t2)))		/* prevent overflow */		return t1 + t2;	return INVALID_ABSTIME;}/* *		timemi			- returns the value of (abstime t1 - reltime t2) */AbsoluteTimetimemi(AbsoluteTime t1, RelativeTime t2){	if (t1 == CURRENT_ABSTIME)		t1 = GetCurrentTransactionStartTime();	if (AbsoluteTimeIsReal(t1) &&		RelativeTimeIsValid(t2) &&		((t2 > 0) ? (t1 > NOSTART_ABSTIME + t2)		 : (t1 < NOEND_ABSTIME + t2)))	/* prevent overflow */		return t1 - t2;	return INVALID_ABSTIME;}/* *		abstimemi		- returns the value of (abstime t1 - abstime t2) */static RelativeTimeabstimemi(AbsoluteTime t1, AbsoluteTime t2){	if (t1 == CURRENT_ABSTIME)		t1 = GetCurrentTransactionStartTime();	if (t2 == CURRENT_ABSTIME)		t2 = GetCurrentTransactionStartTime();	if (AbsoluteTimeIsReal(t1) &&		AbsoluteTimeIsReal(t2))		return t1 - t2;	return INVALID_RELTIME;}/* *		ininterval		- returns 1, iff absolute date is in the interval */intininterval(AbsoluteTime t, TimeInterval interval){	if (interval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME)		return (abstimege(t, interval->data[0]) &&				abstimele(t, interval->data[1]));	return 0;}/* *		intervalrel		- returns  relative time corresponding to interval */RelativeTimeintervalrel(TimeInterval interval){	if (interval->status == T_INTERVAL_VALID)		return abstimemi(interval->data[1], interval->data[0]);	else		return INVALID_RELTIME;}/* *		timenow			- returns  time "now", internal format * *		Now AbsoluteTime is time since Jan 1 1970 -mer 7 Feb 1992 */AbsoluteTimetimenow(){	time_t		sec;	if (time(&sec) < 0)		return INVALID_ABSTIME;	return (AbsoluteTime) sec;}/* *		reltimeeq		- returns 1, iff arguments are equal *		reltimene		- returns 1, iff arguments are not equal *		reltimelt		- returns 1, iff t1 less than t2 *		reltimegt		- returns 1, iff t1 greater than t2 *		reltimele		- returns 1, iff t1 less than or equal to t2 *		reltimege		- returns 1, iff t1 greater than or equal to t2 */boolreltimeeq(RelativeTime t1, RelativeTime t2){	if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)		return 0;	return t1 == t2;}boolreltimene(RelativeTime t1, RelativeTime t2){	if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)		return 0;	return t1 != t2;}boolreltimelt(RelativeTime t1, RelativeTime t2){	if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)		return 0;	return t1 < t2;}boolreltimegt(RelativeTime t1, RelativeTime t2){	if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)		return 0;	return t1 > t2;}boolreltimele(RelativeTime t1, RelativeTime t2){	if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)		return 0;	return t1 <= t2;}boolreltimege(RelativeTime t1, RelativeTime t2){	if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)		return 0;	return t1 >= t2;}/* *		intervalsame	- returns 1, iff interval i1 is same as interval i2 *		Check begin and end time. */boolintervalsame(TimeInterval i1, TimeInterval i2){	if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)		return FALSE;			/* invalid interval */	return (abstimeeq(i1->data[0], i2->data[0]) &&			abstimeeq(i1->data[1], i2->data[1]));}	/* intervalsame() *//* *		intervaleq		- returns 1, iff interval i1 is equal to interval i2 *		Check length of intervals. */boolintervaleq(TimeInterval i1, TimeInterval i2){	AbsoluteTime t10,				t11,				t20,				t21;	if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)		return FALSE;			/* invalid interval */	t10 = i1->data[0];	t11 = i1->data[1];	t20 = i2->data[0];	t21 = i2->data[1];	if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)		|| (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))		return FALSE;	if (t10 == CURRENT_ABSTIME)		t10 = GetCurrentTransactionStartTime();	if (t11 == CURRENT_ABSTIME)		t11 = GetCurrentTransactionStartTime();	if (t20 == CURRENT_ABSTIME)		t20 = GetCurrentTransactionStartTime();	if (t21 == CURRENT_ABSTIME)		t21 = GetCurrentTransactionStartTime();	return (t11 - t10) == (t21 - t20);}	/* intervaleq() *//* *		intervalne		- returns 1, iff interval i1 is not equal to interval i2 *		Check length of intervals. */boolintervalne(TimeInterval i1, TimeInterval i2){	AbsoluteTime t10,				t11,				t20,				t21;	if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)		return FALSE;			/* invalid interval */	t10 = i1->data[0];	t11 = i1->data[1];	t20 = i2->data[0];	t21 = i2->data[1];	if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)		|| (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))		return FALSE;	if (t10 == CURRENT_ABSTIME)		t10 = GetCurrentTransactionStartTime();	if (t11 == CURRENT_ABSTIME)		t11 = GetCurrentTransactionStartTime();	if (t20 == CURRENT_ABSTIME)		t20 = GetCurrentTransactionStartTime();	if (t21 == CURRENT_ABSTIME)		t21 = GetCurrentTransactionStartTime();	return (t11 - t10) != (t21 - t20);

⌨️ 快捷键说明

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