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

📄 dt.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 5 页
字号:
/*------------------------------------------------------------------------- * * dt.c *	  Functions for the built-in type "dt". * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/utils/adt/dt.c,v 1.72.2.1 1999/08/02 05:24:51 scrappy Exp $ * *------------------------------------------------------------------------- */#include <ctype.h>#include <math.h>#include <sys/types.h>#include <errno.h>#include "postgres.h"#ifdef HAVE_FLOAT_H#include <float.h>#endif#ifdef HAVE_LIMITS_H#include <limits.h>#endif#ifndef USE_POSIX_TIME#include <sys/timeb.h>#endif#include "miscadmin.h"#include "utils/builtins.h"static int	DecodeDate(char *str, int fmask, int *tmask, struct tm * tm);static int DecodeNumber(int flen, char *field,	int fmask, int *tmask, struct tm * tm, double *fsec, int *is2digits);static int DecodeNumberField(int len, char *str,	int fmask, int *tmask, struct tm * tm, double *fsec, int *is2digits);static int	DecodeSpecial(int field, char *lowtoken, int *val);static int DecodeTime(char *str, int fmask, int *tmask,		   struct tm * tm, double *fsec);static int	DecodeTimezone(char *str, int *tzp);static int	DecodeUnits(int field, char *lowtoken, int *val);static int	EncodeSpecialDateTime(DateTime dt, char *str);static datetkn *datebsearch(char *key, datetkn *base, unsigned int nel);static DateTime dt2local(DateTime dt, int timezone);static void dt2time(DateTime dt, int *hour, int *min, double *sec);static int	j2day(int jd);static double time2t(const int hour, const int min, const double sec);static int	timespan2tm(TimeSpan span, struct tm * tm, float8 *fsec);static int	tm2timespan(struct tm * tm, double fsec, TimeSpan *span);#define USE_DATE_CACHE 1#define ROUND_ALL 0int			day_tab[2][13] = {	{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0},{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}};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};/* TMODULO() * Macro to replace modf(), which is broken on some platforms. */#define TMODULO(t,q,u) \do { \	q = ((t < 0)? ceil(t / u): floor(t / u)); \	if (q != 0) \		t -= rint(q * u); \} while(0)static void GetEpochTime(struct tm * tm);#define UTIME_MINYEAR (1901)#define UTIME_MINMONTH (12)#define UTIME_MINDAY (14)#define UTIME_MAXYEAR (2038)#define UTIME_MAXMONTH (01)#define UTIME_MAXDAY (18)#define IS_VALID_UTIME(y,m,d) (((y > UTIME_MINYEAR) \ || ((y == UTIME_MINYEAR) && ((m > UTIME_MINMONTH) \  || ((m == UTIME_MINMONTH) && (d >= UTIME_MINDAY))))) \ && ((y < UTIME_MAXYEAR) \ || ((y == UTIME_MAXYEAR) && ((m < UTIME_MAXMONTH) \  || ((m == UTIME_MAXMONTH) && (d <= UTIME_MAXDAY))))))/***************************************************************************** *	 USER I/O ROUTINES														 * *****************************************************************************//* datetime_in() * Convert a string to internal form. */DateTime   *datetime_in(char *str){	DateTime   *result;	double		fsec;	struct tm	tt,			   *tm = &tt;	int			tz;	int			dtype;	int			nf;	char	   *field[MAXDATEFIELDS];	int			ftype[MAXDATEFIELDS];	char		lowstr[MAXDATELEN + 1];	if (!PointerIsValid(str))		elog(ERROR, "Bad (null) datetime external representation", NULL);	if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)	  || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))		elog(ERROR, "Bad datetime external representation '%s'", str);	result = palloc(sizeof(DateTime));	switch (dtype)	{		case DTK_DATE:			if (tm2datetime(tm, fsec, &tz, result) != 0)				elog(ERROR, "Datetime out of range '%s'", str);#ifdef DATEDEBUG			printf("datetime_in- date is %f\n", *result);#endif			break;		case DTK_EPOCH:			DATETIME_EPOCH(*result);			break;		case DTK_CURRENT:			DATETIME_CURRENT(*result);			break;		case DTK_LATE:			DATETIME_NOEND(*result);			break;		case DTK_EARLY:			DATETIME_NOBEGIN(*result);			break;		case DTK_INVALID:			DATETIME_INVALID(*result);			break;		default:			elog(ERROR, "Internal coding error, can't input datetime '%s'", str);	}	return result;}	/* datetime_in() *//* datetime_out() * Convert a datetime to external form. */char *datetime_out(DateTime *dt){	char	   *result;	int			tz;	struct tm	tt,			   *tm = &tt;	double		fsec;	char	   *tzn;	char		buf[MAXDATELEN + 1];	if (!PointerIsValid(dt))		return NULL;	if (DATETIME_IS_RESERVED(*dt))	{		EncodeSpecialDateTime(*dt, buf);	}	else if (datetime2tm(*dt, &tz, tm, &fsec, &tzn) == 0)	{		EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);	}	else		EncodeSpecialDateTime(DT_INVALID, buf);	result = palloc(strlen(buf) + 1);	strcpy(result, buf);	return result;}	/* datetime_out() *//* timespan_in() * Convert a string to internal form. * * External format(s): *	Uses the generic date/time parsing and decoding routines. */TimeSpan   *timespan_in(char *str){	TimeSpan   *span;	double		fsec;	struct tm	tt,			   *tm = &tt;	int			dtype;	int			nf;	char	   *field[MAXDATEFIELDS];	int			ftype[MAXDATEFIELDS];	char		lowstr[MAXDATELEN + 1];	tm->tm_year = 0;	tm->tm_mon = 0;	tm->tm_mday = 0;	tm->tm_hour = 0;	tm->tm_min = 0;	tm->tm_sec = 0;	fsec = 0;	if (!PointerIsValid(str))		elog(ERROR, "Bad (null) timespan external representation", NULL);	if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)		|| (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0))		elog(ERROR, "Bad timespan external representation '%s'", str);	span = palloc(sizeof(TimeSpan));	switch (dtype)	{		case DTK_DELTA:			if (tm2timespan(tm, fsec, span) != 0)			{#if NOT_USED				TIMESPAN_INVALID(span);#endif				elog(ERROR, "Bad timespan external representation '%s'", str);			}			break;		default:			elog(ERROR, "Internal coding error, can't input timespan '%s'", str);	}	return span;}	/* timespan_in() *//* timespan_out() * Convert a time span to external form. */char *timespan_out(TimeSpan *span){	char	   *result;	struct tm	tt,			   *tm = &tt;	double		fsec;	char		buf[MAXDATELEN + 1];	if (!PointerIsValid(span))		return NULL;	if (timespan2tm(*span, tm, &fsec) != 0)		return NULL;	if (EncodeTimeSpan(tm, fsec, DateStyle, buf) != 0)		elog(ERROR, "Unable to format timespan", NULL);	result = palloc(strlen(buf) + 1);	strcpy(result, buf);	return result;}	/* timespan_out() *//***************************************************************************** *	 PUBLIC ROUTINES														 * *****************************************************************************/booldatetime_finite(DateTime *datetime){	if (!PointerIsValid(datetime))		return FALSE;	return !DATETIME_NOT_FINITE(*datetime);}	/* datetime_finite() */booltimespan_finite(TimeSpan *timespan){	if (!PointerIsValid(timespan))		return FALSE;	return !TIMESPAN_NOT_FINITE(*timespan);}	/* timespan_finite() *//*---------------------------------------------------------- *	Relational operators for datetime. *---------------------------------------------------------*/static 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++;#ifdef DATEDEBUG	printf("GetEpochTime- %04d-%02d-%02d %02d:%02d:%02d\n",		   tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);#endif	return;}	/* GetEpochTime() */DateTimeSetDateTime(DateTime dt){	struct tm	tt;	if (DATETIME_IS_CURRENT(dt))	{		GetCurrentTime(&tt);		tm2datetime(&tt, 0, NULL, &dt);		dt = dt2local(dt, -CTimeZone);#ifdef DATEDEBUG		printf("SetDateTime- current time is %f\n", dt);#endif	}	else	{							/* if (DATETIME_IS_EPOCH(dt1)) */		GetEpochTime(&tt);		tm2datetime(&tt, 0, NULL, &dt);#ifdef DATEDEBUG		printf("SetDateTime- epoch time is %f\n", dt);#endif	}	return dt;}	/* SetDateTime() *//*		datetime_relop	- is datetime1 relop datetime2 */booldatetime_eq(DateTime *datetime1, DateTime *datetime2){	DateTime	dt1,				dt2;	if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))		return FALSE;	dt1 = *datetime1;	dt2 = *datetime2;	if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))		return FALSE;	if (DATETIME_IS_RELATIVE(dt1))		dt1 = SetDateTime(dt1);	if (DATETIME_IS_RELATIVE(dt2))		dt2 = SetDateTime(dt2);	return dt1 == dt2;}	/* datetime_eq() */booldatetime_ne(DateTime *datetime1, DateTime *datetime2){	DateTime	dt1,				dt2;	if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))		return FALSE;	dt1 = *datetime1;	dt2 = *datetime2;	if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))		return FALSE;	if (DATETIME_IS_RELATIVE(dt1))		dt1 = SetDateTime(dt1);	if (DATETIME_IS_RELATIVE(dt2))		dt2 = SetDateTime(dt2);	return dt1 != dt2;}	/* datetime_ne() */booldatetime_lt(DateTime *datetime1, DateTime *datetime2){	DateTime	dt1,				dt2;	if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))		return FALSE;	dt1 = *datetime1;	dt2 = *datetime2;	if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))		return FALSE;	if (DATETIME_IS_RELATIVE(dt1))		dt1 = SetDateTime(dt1);	if (DATETIME_IS_RELATIVE(dt2))		dt2 = SetDateTime(dt2);	return dt1 < dt2;}	/* datetime_lt() */booldatetime_gt(DateTime *datetime1, DateTime *datetime2){	DateTime	dt1,				dt2;	if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))		return FALSE;	dt1 = *datetime1;	dt2 = *datetime2;	if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))		return FALSE;	if (DATETIME_IS_RELATIVE(dt1))		dt1 = SetDateTime(dt1);	if (DATETIME_IS_RELATIVE(dt2))		dt2 = SetDateTime(dt2);#ifdef DATEDEBUG	printf("datetime_gt- %f %s greater than %f\n", dt1, ((dt1 > dt2) ? "is" : "is not"), dt2);#endif	return dt1 > dt2;}	/* datetime_gt() */booldatetime_le(DateTime *datetime1, DateTime *datetime2){	DateTime	dt1,				dt2;	if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))		return FALSE;	dt1 = *datetime1;	dt2 = *datetime2;	if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))		return FALSE;	if (DATETIME_IS_RELATIVE(dt1))		dt1 = SetDateTime(dt1);	if (DATETIME_IS_RELATIVE(dt2))		dt2 = SetDateTime(dt2);	return dt1 <= dt2;}	/* datetime_le() */booldatetime_ge(DateTime *datetime1, DateTime *datetime2){	DateTime	dt1,				dt2;	if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))		return FALSE;	dt1 = *datetime1;	dt2 = *datetime2;	if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))		return FALSE;	if (DATETIME_IS_RELATIVE(dt1))		dt1 = SetDateTime(dt1);	if (DATETIME_IS_RELATIVE(dt2))		dt2 = SetDateTime(dt2);	return dt1 >= dt2;}	/* datetime_ge() *//*		datetime_cmp	- 3-state comparison for datetime *		collate invalid datetime at the end */intdatetime_cmp(DateTime *datetime1, DateTime *datetime2){	DateTime	dt1,				dt2;	if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))		return 0;	dt1 = *datetime1;	dt2 = *datetime2;	if (DATETIME_IS_INVALID(dt1))	{		return (DATETIME_IS_INVALID(dt2) ? 0 : 1);	}	else if (DATETIME_IS_INVALID(dt2))	{		return -1;	}	else	{		if (DATETIME_IS_RELATIVE(dt1))			dt1 = SetDateTime(dt1);		if (DATETIME_IS_RELATIVE(dt2))			dt2 = SetDateTime(dt2);	}	return ((dt1 < dt2) ? -1 : ((dt1 > dt2) ? 1 : 0));}	/* datetime_cmp() *//*		timespan_relop	- is timespan1 relop timespan2 */booltimespan_eq(TimeSpan *timespan1, TimeSpan *timespan2){	if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))		return FALSE;	if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))		return FALSE;	return ((timespan1->time == timespan2->time)			&& (timespan1->month == timespan2->month));}	/* timespan_eq() */booltimespan_ne(TimeSpan *timespan1, TimeSpan *timespan2){	if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))		return FALSE;	if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))

⌨️ 快捷键说明

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