1998-12-14 09:11:17 +01:00
|
|
|
/*
|
1999-02-14 00:22:53 +01:00
|
|
|
* nabstime.c
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
* Utilities for the built-in type "AbsoluteTime".
|
|
|
|
* Functions for the built-in type "RelativeTime".
|
|
|
|
* Functions for the built-in type "TimeInterval".
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
* IDENTIFICATION
|
2000-04-12 19:17:23 +02:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.67 2000/04/12 17:15:50 momjian Exp $
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
#include <ctype.h>
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
#include <time.h>
|
|
|
|
#include <sys/time.h>
|
1996-07-09 08:22:35 +02:00
|
|
|
#include <sys/types.h>
|
1997-01-10 21:19:49 +01:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "postgres.h"
|
1997-03-26 04:14:37 +01:00
|
|
|
#ifdef HAVE_FLOAT_H
|
1997-09-07 07:04:48 +02:00
|
|
|
#include <float.h>
|
1997-03-26 04:14:37 +01:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
1997-03-28 07:54:51 +01:00
|
|
|
#ifdef HAVE_LIMITS_H
|
1997-09-07 07:04:48 +02:00
|
|
|
#include <limits.h>
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
#ifndef MAXINT
|
|
|
|
#define MAXINT INT_MAX
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
#ifdef HAVE_VALUES_H
|
|
|
|
#include <values.h>
|
|
|
|
#endif
|
1997-03-28 07:54:51 +01:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
1997-01-10 19:22:41 +01:00
|
|
|
#ifndef USE_POSIX_TIME
|
|
|
|
#include <sys/timeb.h>
|
|
|
|
#endif
|
1999-07-16 07:00:38 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "access/xact.h"
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "miscadmin.h"
|
|
|
|
#include "utils/builtins.h"
|
1996-07-09 08:22:35 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
#if 0
|
1997-09-07 07:04:48 +02:00
|
|
|
static AbsoluteTime tm2abstime(struct tm * tm, int tz);
|
2000-04-12 19:17:23 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
#endif
|
|
|
|
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
#define MIN_DAYNUM -24856 /* December 13, 1901 */
|
|
|
|
#define MAX_DAYNUM 24854 /* January 18, 2038 */
|
1996-07-09 08:22:35 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
#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
|
|
|
|
* for these 4-byte types.
|
|
|
|
*
|
|
|
|
* "tinterval" is two 4-byte fields.
|
|
|
|
* Definitions for parsing tinterval.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#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_USED
|
|
|
|
static 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};
|
2000-04-12 19:17:23 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Function prototypes -- internal to this file only
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void reltime2tm(RelativeTime time, struct tm * tm);
|
|
|
|
|
|
|
|
#ifdef NOT_USED
|
|
|
|
static int correct_unit(char *unit, int *unptr);
|
|
|
|
static int correct_dir(char *direction, int *signptr);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int istinterval(char *i_string,
|
|
|
|
AbsoluteTime *i_start,
|
|
|
|
AbsoluteTime *i_end);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-03-18 17:36:50 +01:00
|
|
|
/* GetCurrentAbsoluteTime()
|
|
|
|
* Get the current system time. Set timezone parameters if not specified elsewhere.
|
|
|
|
* Define HasTZSet to allow clients to specify the default timezone.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Returns the number of seconds since epoch (January 1 1970 GMT)
|
|
|
|
*/
|
|
|
|
AbsoluteTime
|
1997-03-15 00:21:12 +01:00
|
|
|
GetCurrentAbsoluteTime(void)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
time_t now;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-03-15 00:21:12 +01:00
|
|
|
#ifdef USE_POSIX_TIME
|
1997-09-08 04:41:22 +02:00
|
|
|
struct tm *tm;
|
1997-04-25 20:40:50 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
now = time(NULL);
|
|
|
|
#else /* ! USE_POSIX_TIME */
|
1997-09-08 04:41:22 +02:00
|
|
|
struct timeb tb; /* the old V7-ism */
|
1997-03-18 17:36:50 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
ftime(&tb);
|
|
|
|
now = tb.time;
|
1997-03-18 17:36:50 +01:00
|
|
|
#endif
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (!HasCTZSet)
|
|
|
|
{
|
1997-03-18 17:36:50 +01:00
|
|
|
#ifdef USE_POSIX_TIME
|
1998-12-31 17:30:59 +01:00
|
|
|
#if defined(HAVE_TM_ZONE)
|
1997-09-07 07:04:48 +02:00
|
|
|
tm = localtime(&now);
|
|
|
|
|
|
|
|
CTimeZone = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
|
|
|
|
CDayLight = (tm->tm_isdst > 0);
|
|
|
|
|
1999-02-21 04:49:55 +01:00
|
|
|
#ifdef NOT_USED
|
1999-05-25 18:15:34 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
|
|
|
* XXX is there a better way to get local timezone string w/o
|
|
|
|
* tzname? - tgl 97/03/18
|
|
|
|
*/
|
|
|
|
strftime(CTZName, MAXTZLEN, "%Z", tm);
|
1998-12-14 00:34:17 +01:00
|
|
|
#endif
|
1999-05-25 18:15:34 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX FreeBSD man pages indicate that this should work - thomas
|
|
|
|
* 1998-12-12
|
|
|
|
*/
|
1998-12-15 16:28:57 +01:00
|
|
|
strcpy(CTZName, tm->tm_zone);
|
1998-12-14 00:34:17 +01:00
|
|
|
|
|
|
|
#elif defined(HAVE_INT_TIMEZONE)
|
|
|
|
tm = localtime(&now);
|
|
|
|
|
|
|
|
CDayLight = tm->tm_isdst;
|
1999-04-26 06:42:49 +02:00
|
|
|
CTimeZone =
|
|
|
|
#ifdef __CYGWIN32__
|
1999-05-25 18:15:34 +02:00
|
|
|
(tm->tm_isdst ? (_timezone - 3600) : _timezone);
|
1999-04-26 06:42:49 +02:00
|
|
|
#else
|
1999-05-25 18:15:34 +02:00
|
|
|
(tm->tm_isdst ? (timezone - 3600) : timezone);
|
|
|
|
#endif
|
1998-12-14 00:34:17 +01:00
|
|
|
strcpy(CTZName, tzname[tm->tm_isdst]);
|
|
|
|
#else
|
|
|
|
#error USE_POSIX_TIME defined but no time zone available
|
1997-09-07 07:04:48 +02:00
|
|
|
#endif
|
|
|
|
#else /* ! USE_POSIX_TIME */
|
|
|
|
CTimeZone = tb.timezone * 60;
|
|
|
|
CDayLight = (tb.dstflag != 0);
|
|
|
|
|
1999-05-25 18:15:34 +02:00
|
|
|
/*
|
|
|
|
* XXX does this work to get the local timezone string in V7? -
|
|
|
|
* tgl 97/03/18
|
1997-09-07 07:04:48 +02:00
|
|
|
*/
|
|
|
|
strftime(CTZName, MAXTZLEN, "%Z", localtime(&now));
|
1996-10-18 01:59:45 +02:00
|
|
|
#endif
|
1997-09-07 07:04:48 +02:00
|
|
|
};
|
1997-03-18 17:36:50 +01:00
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return (AbsoluteTime) now;
|
1998-02-26 05:46:47 +01:00
|
|
|
} /* GetCurrentAbsoluteTime() */
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
|
1997-03-15 00:21:12 +01:00
|
|
|
void
|
1997-09-07 07:04:48 +02:00
|
|
|
GetCurrentTime(struct tm * tm)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int tz;
|
1997-04-25 20:40:50 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
abstime2tm(GetCurrentTransactionStartTime(), &tz, tm, NULL);
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
return;
|
1998-02-26 05:46:47 +01:00
|
|
|
} /* GetCurrentTime() */
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
|
|
|
|
|
|
|
void
|
1997-09-07 07:04:48 +02:00
|
|
|
abstime2tm(AbsoluteTime time, int *tzp, struct tm * tm, char *tzn)
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
{
|
1997-06-23 16:56:15 +02:00
|
|
|
#ifdef USE_POSIX_TIME
|
1997-09-08 04:41:22 +02:00
|
|
|
struct tm *tx;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
#else /* ! USE_POSIX_TIME */
|
1997-09-08 04:41:22 +02:00
|
|
|
struct timeb tb; /* the old V7-ism */
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
ftime(&tb);
|
1997-04-22 19:36:57 +02:00
|
|
|
#endif
|
1997-06-23 16:56:15 +02:00
|
|
|
|
|
|
|
#ifdef USE_POSIX_TIME
|
1997-09-07 07:04:48 +02:00
|
|
|
if (tzp != NULL)
|
1997-09-08 23:56:23 +02:00
|
|
|
tx = localtime((time_t *) &time);
|
1997-09-07 07:04:48 +02:00
|
|
|
else
|
|
|
|
{
|
1997-09-08 23:56:23 +02:00
|
|
|
tx = gmtime((time_t *) &time);
|
1997-09-07 07:04:48 +02:00
|
|
|
};
|
1997-06-23 16:56:15 +02:00
|
|
|
#endif
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-10-30 15:06:47 +01:00
|
|
|
#ifdef USE_POSIX_TIME
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
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;
|
1997-06-23 16:56:15 +02:00
|
|
|
|
1998-12-31 17:30:59 +01:00
|
|
|
#if defined(HAVE_TM_ZONE)
|
1997-09-07 07:04:48 +02:00
|
|
|
tm->tm_gmtoff = tx->tm_gmtoff;
|
|
|
|
tm->tm_zone = tx->tm_zone;
|
|
|
|
|
|
|
|
if (tzp != NULL)
|
|
|
|
*tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
|
|
|
|
/* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */
|
|
|
|
if (tzn != NULL)
|
1999-12-09 06:02:24 +01:00
|
|
|
{
|
2000-04-12 19:17:23 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
|
|
|
|
* contains an error message, which doesn't fit in the buffer
|
|
|
|
*/
|
1999-12-09 06:02:24 +01:00
|
|
|
strncpy(tzn, tm->tm_zone, MAXTZLEN);
|
|
|
|
if (strlen(tm->tm_zone) > MAXTZLEN)
|
|
|
|
{
|
|
|
|
tzn[MAXTZLEN] = '\0';
|
|
|
|
elog(NOTICE, "Invalid timezone \'%s\'", tm->tm_zone);
|
|
|
|
}
|
|
|
|
}
|
1998-12-14 00:34:17 +01:00
|
|
|
#elif defined(HAVE_INT_TIMEZONE)
|
|
|
|
if (tzp != NULL)
|
1999-04-26 06:42:49 +02:00
|
|
|
#ifdef __CYGWIN__
|
|
|
|
*tzp = (tm->tm_isdst ? (_timezone - 3600) : _timezone);
|
|
|
|
#else
|
1998-12-14 00:34:17 +01:00
|
|
|
*tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
|
1999-04-26 06:42:49 +02:00
|
|
|
#endif
|
1998-12-14 00:34:17 +01:00
|
|
|
if (tzn != NULL)
|
1999-12-09 06:02:24 +01:00
|
|
|
{
|
2000-04-12 19:17:23 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
|
|
|
|
* contains an error message, which doesn't fit in the buffer
|
|
|
|
*/
|
1999-12-09 06:02:24 +01:00
|
|
|
strncpy(tzn, tzname[tm->tm_isdst], MAXTZLEN);
|
|
|
|
if (strlen(tzname[tm->tm_isdst]) > MAXTZLEN)
|
|
|
|
{
|
|
|
|
tzn[MAXTZLEN] = '\0';
|
|
|
|
elog(NOTICE, "Invalid timezone \'%s\'", tzname[tm->tm_isdst]);
|
|
|
|
}
|
|
|
|
}
|
1998-12-31 17:30:59 +01:00
|
|
|
#else
|
1998-12-14 00:34:17 +01:00
|
|
|
#error POSIX time support is broken
|
1997-09-07 07:04:48 +02:00
|
|
|
#endif
|
|
|
|
#else /* ! USE_POSIX_TIME */
|
|
|
|
if (tzp != NULL)
|
|
|
|
*tzp = tb.timezone * 60;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX does this work to get the local timezone string in V7? - tgl
|
|
|
|
* 97/03/18
|
|
|
|
*/
|
|
|
|
if (tzn != NULL)
|
|
|
|
strftime(tzn, MAXTZLEN, "%Z", localtime(&now));
|
1997-06-23 16:56:15 +02:00
|
|
|
#endif
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
return;
|
1998-02-26 05:46:47 +01:00
|
|
|
} /* abstime2tm() */
|
1997-03-15 00:21:12 +01:00
|
|
|
|
|
|
|
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
/* tm2abstime()
|
|
|
|
* Convert a tm structure to abstime.
|
|
|
|
* Note that tm has full year (not 1900-based) and 1-based month.
|
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static AbsoluteTime
|
1997-09-07 07:04:48 +02:00
|
|
|
tm2abstime(struct tm * tm, int tz)
|
1997-03-25 09:11:24 +01:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int day,
|
|
|
|
sec;
|
1997-03-25 09:11:24 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/* validate, before going out of range on some members */
|
|
|
|
if (tm->tm_year < 1901 || tm->tm_year > 2038
|
|
|
|
|| tm->tm_mon < 1 || tm->tm_mon > 12
|
|
|
|
|| tm->tm_mday < 1 || tm->tm_mday > 31
|
|
|
|
|| tm->tm_hour < 0 || tm->tm_hour >= 24
|
|
|
|
|| tm->tm_min < 0 || tm->tm_min > 59
|
|
|
|
|| tm->tm_sec < 0 || tm->tm_sec > 59)
|
1998-09-01 05:29:17 +02:00
|
|
|
return INVALID_ABSTIME;
|
1997-03-25 09:11:24 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
day = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(1970, 1, 1));
|
1997-03-25 09:11:24 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/* check for time out of range */
|
|
|
|
if ((day < MIN_DAYNUM) || (day > MAX_DAYNUM))
|
1998-09-01 05:29:17 +02:00
|
|
|
return INVALID_ABSTIME;
|
1997-03-25 09:11:24 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/* convert to seconds */
|
|
|
|
sec = tm->tm_sec + tz + (tm->tm_min + (day * 24 + tm->tm_hour) * 60) * 60;
|
1997-03-25 09:11:24 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/* check for overflow */
|
|
|
|
if ((day == MAX_DAYNUM && sec < 0) ||
|
|
|
|
(day == MIN_DAYNUM && sec > 0))
|
1998-09-01 05:29:17 +02:00
|
|
|
return INVALID_ABSTIME;
|
1997-03-25 09:11:24 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/* check for reserved values (e.g. "current" on edge of usual range */
|
|
|
|
if (!AbsoluteTimeIsReal(sec))
|
1998-09-01 05:29:17 +02:00
|
|
|
return INVALID_ABSTIME;
|
1997-03-25 09:11:24 +01:00
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return sec;
|
1998-02-26 05:46:47 +01:00
|
|
|
} /* tm2abstime() */
|
1997-03-25 09:11:24 +01:00
|
|
|
|
|
|
|
|
1997-03-15 00:21:12 +01:00
|
|
|
/* nabstimein()
|
|
|
|
* Decode date/time string and return abstime.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-03-15 00:21:12 +01:00
|
|
|
AbsoluteTime
|
1997-09-07 07:04:48 +02:00
|
|
|
nabstimein(char *str)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
AbsoluteTime result;
|
1997-03-25 09:11:24 +01:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
double fsec;
|
|
|
|
int tz = 0;
|
|
|
|
struct tm date,
|
|
|
|
*tm = &date;
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
char *field[MAXDATEFIELDS];
|
|
|
|
char lowstr[MAXDATELEN + 1];
|
|
|
|
int dtype;
|
|
|
|
int nf,
|
|
|
|
ftype[MAXDATEFIELDS];
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (!PointerIsValid(str))
|
2000-01-15 03:59:43 +01:00
|
|
|
elog(ERROR, "Bad (null) abstime external representation");
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (strlen(str) > MAXDATELEN)
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "Bad (length) abstime external representation '%s'", str);
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|
|
|
|
|| (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "Bad abstime external representation '%s'", str);
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
switch (dtype)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
case DTK_DATE:
|
|
|
|
result = tm2abstime(tm, tz);
|
|
|
|
break;
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case DTK_EPOCH:
|
|
|
|
result = EPOCH_ABSTIME;
|
|
|
|
break;
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case DTK_CURRENT:
|
|
|
|
result = CURRENT_ABSTIME;
|
|
|
|
break;
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case DTK_LATE:
|
|
|
|
result = NOEND_ABSTIME;
|
|
|
|
break;
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case DTK_EARLY:
|
|
|
|
result = NOSTART_ABSTIME;
|
|
|
|
break;
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case DTK_INVALID:
|
|
|
|
result = INVALID_ABSTIME;
|
|
|
|
break;
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
default:
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "Bad abstime (internal coding error) '%s'", str);
|
1997-09-08 04:41:22 +02:00
|
|
|
result = INVALID_ABSTIME;
|
|
|
|
break;
|
1997-09-07 07:04:48 +02:00
|
|
|
};
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
return result;
|
1998-02-26 05:46:47 +01:00
|
|
|
} /* nabstimein() */
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-06-23 16:56:15 +02:00
|
|
|
/* nabstimeout()
|
1996-07-09 08:22:35 +02:00
|
|
|
* Given an AbsoluteTime return the English text version of the date
|
|
|
|
*/
|
1998-02-26 05:46:47 +01:00
|
|
|
char *
|
1996-07-09 08:22:35 +02:00
|
|
|
nabstimeout(AbsoluteTime time)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
char *result;
|
|
|
|
int tz;
|
|
|
|
double fsec = 0;
|
|
|
|
struct tm tt,
|
|
|
|
*tm = &tt;
|
|
|
|
char buf[MAXDATELEN + 1];
|
|
|
|
char zone[MAXDATELEN + 1],
|
|
|
|
*tzn = zone;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
switch (time)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
case EPOCH_ABSTIME:
|
|
|
|
strcpy(buf, EPOCH);
|
|
|
|
break;
|
|
|
|
case INVALID_ABSTIME:
|
|
|
|
strcpy(buf, INVALID);
|
|
|
|
break;
|
|
|
|
case CURRENT_ABSTIME:
|
|
|
|
strcpy(buf, DCURRENT);
|
|
|
|
break;
|
|
|
|
case NOEND_ABSTIME:
|
|
|
|
strcpy(buf, LATE);
|
|
|
|
break;
|
|
|
|
case NOSTART_ABSTIME:
|
|
|
|
strcpy(buf, EARLY);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abstime2tm(time, &tz, tm, tzn);
|
|
|
|
EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
|
|
|
|
break;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1998-01-07 19:47:07 +01:00
|
|
|
result = palloc(strlen(buf) + 1);
|
1997-09-07 07:04:48 +02:00
|
|
|
strcpy(result, buf);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return result;
|
1998-02-26 05:46:47 +01:00
|
|
|
} /* nabstimeout() */
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
1997-09-07 07:04:48 +02:00
|
|
|
* AbsoluteTimeIsBefore -- true iff time1 is before time2.
|
|
|
|
* AbsoluteTimeIsBefore -- true iff time1 is after time2.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
bool
|
|
|
|
AbsoluteTimeIsBefore(AbsoluteTime time1, AbsoluteTime time2)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
Assert(AbsoluteTimeIsValid(time1));
|
|
|
|
Assert(AbsoluteTimeIsValid(time2));
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (time1 == CURRENT_ABSTIME)
|
|
|
|
time1 = GetCurrentTransactionStartTime();
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (time2 == CURRENT_ABSTIME)
|
|
|
|
time2 = GetCurrentTransactionStartTime();
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return time1 < time2;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1998-10-08 20:30:52 +02:00
|
|
|
#ifdef NOT_USED
|
1996-07-09 08:22:35 +02:00
|
|
|
bool
|
|
|
|
AbsoluteTimeIsAfter(AbsoluteTime time1, AbsoluteTime time2)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
Assert(AbsoluteTimeIsValid(time1));
|
|
|
|
Assert(AbsoluteTimeIsValid(time2));
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (time1 == CURRENT_ABSTIME)
|
|
|
|
time1 = GetCurrentTransactionStartTime();
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (time2 == CURRENT_ABSTIME)
|
|
|
|
time2 = GetCurrentTransactionStartTime();
|
1997-03-15 00:21:12 +01:00
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return time1 > time2;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1999-05-25 18:15:34 +02:00
|
|
|
|
1998-10-08 20:30:52 +02:00
|
|
|
#endif
|
1996-07-09 08:22:35 +02:00
|
|
|
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
/* abstime_finite()
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
abstime_finite(AbsoluteTime abstime)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
return ((abstime != INVALID_ABSTIME)
|
|
|
|
&& (abstime != NOSTART_ABSTIME) && (abstime != NOEND_ABSTIME));
|
1998-02-26 05:46:47 +01:00
|
|
|
} /* abstime_finite() */
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
1997-09-07 07:04:48 +02:00
|
|
|
* abstimeeq - returns 1, iff arguments are equal
|
|
|
|
* abstimene - returns 1, iff arguments are not equal
|
|
|
|
* abstimelt - returns 1, iff t1 less than t2
|
|
|
|
* abstimegt - returns 1, iff t1 greater than t2
|
|
|
|
* abstimele - returns 1, iff t1 less than or equal to t2
|
|
|
|
* abstimege - returns 1, iff t1 greater than or equal to t2
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-03-15 00:21:12 +01:00
|
|
|
bool
|
1996-07-09 08:22:35 +02:00
|
|
|
abstimeeq(AbsoluteTime t1, AbsoluteTime t2)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
|
1998-09-01 05:29:17 +02:00
|
|
|
return FALSE;
|
1997-09-07 07:04:48 +02:00
|
|
|
if (t1 == CURRENT_ABSTIME)
|
|
|
|
t1 = GetCurrentTransactionStartTime();
|
|
|
|
if (t2 == CURRENT_ABSTIME)
|
|
|
|
t2 = GetCurrentTransactionStartTime();
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return t1 == t2;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-03-15 00:21:12 +01:00
|
|
|
bool
|
1996-07-09 08:22:35 +02:00
|
|
|
abstimene(AbsoluteTime t1, AbsoluteTime t2)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
|
1998-09-01 05:29:17 +02:00
|
|
|
return FALSE;
|
1997-09-07 07:04:48 +02:00
|
|
|
if (t1 == CURRENT_ABSTIME)
|
|
|
|
t1 = GetCurrentTransactionStartTime();
|
|
|
|
if (t2 == CURRENT_ABSTIME)
|
|
|
|
t2 = GetCurrentTransactionStartTime();
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return t1 != t2;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-03-15 00:21:12 +01:00
|
|
|
bool
|
1996-07-09 08:22:35 +02:00
|
|
|
abstimelt(AbsoluteTime t1, AbsoluteTime t2)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
|
1998-09-01 05:29:17 +02:00
|
|
|
return FALSE;
|
1997-09-07 07:04:48 +02:00
|
|
|
if (t1 == CURRENT_ABSTIME)
|
|
|
|
t1 = GetCurrentTransactionStartTime();
|
|
|
|
if (t2 == CURRENT_ABSTIME)
|
|
|
|
t2 = GetCurrentTransactionStartTime();
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return t1 < t2;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-03-15 00:21:12 +01:00
|
|
|
bool
|
1996-07-09 08:22:35 +02:00
|
|
|
abstimegt(AbsoluteTime t1, AbsoluteTime t2)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
|
1998-09-01 05:29:17 +02:00
|
|
|
return FALSE;
|
1997-09-07 07:04:48 +02:00
|
|
|
if (t1 == CURRENT_ABSTIME)
|
|
|
|
t1 = GetCurrentTransactionStartTime();
|
|
|
|
if (t2 == CURRENT_ABSTIME)
|
|
|
|
t2 = GetCurrentTransactionStartTime();
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return t1 > t2;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-03-15 00:21:12 +01:00
|
|
|
bool
|
1996-07-09 08:22:35 +02:00
|
|
|
abstimele(AbsoluteTime t1, AbsoluteTime t2)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
|
1998-09-01 05:29:17 +02:00
|
|
|
return FALSE;
|
1997-09-07 07:04:48 +02:00
|
|
|
if (t1 == CURRENT_ABSTIME)
|
|
|
|
t1 = GetCurrentTransactionStartTime();
|
|
|
|
if (t2 == CURRENT_ABSTIME)
|
|
|
|
t2 = GetCurrentTransactionStartTime();
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return t1 <= t2;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-03-15 00:21:12 +01:00
|
|
|
bool
|
1996-07-09 08:22:35 +02:00
|
|
|
abstimege(AbsoluteTime t1, AbsoluteTime t2)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
|
1998-09-01 05:29:17 +02:00
|
|
|
return FALSE;
|
1997-09-07 07:04:48 +02:00
|
|
|
if (t1 == CURRENT_ABSTIME)
|
|
|
|
t1 = GetCurrentTransactionStartTime();
|
|
|
|
if (t2 == CURRENT_ABSTIME)
|
|
|
|
t2 = GetCurrentTransactionStartTime();
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return t1 >= t2;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-03-25 09:11:24 +01:00
|
|
|
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
1997-03-25 09:11:24 +01:00
|
|
|
/* datetime_abstime()
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
* Convert timestamp to abstime.
|
1997-03-25 09:11:24 +01:00
|
|
|
*/
|
|
|
|
AbsoluteTime
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
timestamp_abstime(Timestamp *timestamp)
|
1997-03-25 09:11:24 +01:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
AbsoluteTime result;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
double fsec;
|
|
|
|
struct tm tt,
|
|
|
|
*tm = &tt;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
if (!PointerIsValid(timestamp))
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
result = INVALID_ABSTIME;
|
|
|
|
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
else if (TIMESTAMP_IS_INVALID(*timestamp))
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
result = INVALID_ABSTIME;
|
|
|
|
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
else if (TIMESTAMP_IS_NOBEGIN(*timestamp))
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
result = NOSTART_ABSTIME;
|
|
|
|
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
else if (TIMESTAMP_IS_NOEND(*timestamp))
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
result = NOEND_ABSTIME;
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
if (TIMESTAMP_IS_RELATIVE(*timestamp))
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
timestamp2tm(SetTimestamp(*timestamp), NULL, tm, &fsec, NULL);
|
1997-09-07 07:04:48 +02:00
|
|
|
result = tm2abstime(tm, 0);
|
|
|
|
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
else if (timestamp2tm(*timestamp, NULL, tm, &fsec, NULL) == 0)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
result = tm2abstime(tm, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result = INVALID_ABSTIME;
|
|
|
|
};
|
1997-03-25 09:11:24 +01:00
|
|
|
};
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return result;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
} /* timestamp_abstime() */
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
/* abstime_timestamp()
|
|
|
|
* Convert abstime to timestamp.
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
*/
|
2000-04-12 19:17:23 +02:00
|
|
|
Timestamp *
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
abstime_timestamp(AbsoluteTime abstime)
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
{
|
2000-04-12 19:17:23 +02:00
|
|
|
Timestamp *result;
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
if (!PointerIsValid(result = palloc(sizeof(Timestamp))))
|
|
|
|
elog(ERROR, "Unable to allocate space to convert abstime to timestamp");
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
switch (abstime)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
case INVALID_ABSTIME:
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
TIMESTAMP_INVALID(*result);
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case NOSTART_ABSTIME:
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
TIMESTAMP_NOBEGIN(*result);
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case NOEND_ABSTIME:
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
TIMESTAMP_NOEND(*result);
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case EPOCH_ABSTIME:
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
TIMESTAMP_EPOCH(*result);
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case CURRENT_ABSTIME:
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
TIMESTAMP_CURRENT(*result);
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
default:
|
|
|
|
*result = abstime + ((date2j(1970, 1, 1) - date2j(2000, 1, 1)) * 86400);
|
|
|
|
break;
|
1997-09-07 07:04:48 +02:00
|
|
|
};
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return result;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
} /* abstime_timestamp() */
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* USER I/O ROUTINES *
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* reltimein - converts a reltime string in an internal format
|
|
|
|
*/
|
|
|
|
RelativeTime
|
|
|
|
reltimein(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");
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
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() */
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
reltime2tm(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_USED
|
|
|
|
int
|
|
|
|
dummyfunc()
|
|
|
|
{
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
TimeInterval
|
|
|
|
tintervalin(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 *
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
RelativeTime
|
|
|
|
interval_reltime(Interval *interval)
|
|
|
|
{
|
|
|
|
RelativeTime time;
|
|
|
|
int year,
|
|
|
|
month;
|
|
|
|
double span;
|
|
|
|
|
|
|
|
if (!PointerIsValid(interval))
|
|
|
|
time = INVALID_RELTIME;
|
|
|
|
|
|
|
|
if (INTERVAL_IS_INVALID(*interval))
|
|
|
|
{
|
|
|
|
time = INVALID_RELTIME;
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (interval->month == 0)
|
|
|
|
{
|
|
|
|
year = 0;
|
|
|
|
month = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
else if (abs(interval->month) >= 12)
|
|
|
|
{
|
|
|
|
year = (interval->month / 12);
|
|
|
|
month = (interval->month % 12);
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
year = 0;
|
|
|
|
month = interval->month;
|
|
|
|
}
|
|
|
|
|
|
|
|
span = (((((double) 365 * year) + ((double) 30 * month)) * 86400) + interval->time);
|
|
|
|
|
|
|
|
time = (((span > INT_MIN) && (span < INT_MAX)) ? span : INVALID_RELTIME);
|
|
|
|
}
|
|
|
|
|
|
|
|
return time;
|
|
|
|
} /* interval_reltime() */
|
|
|
|
|
|
|
|
|
|
|
|
Interval *
|
|
|
|
reltime_interval(RelativeTime reltime)
|
|
|
|
{
|
|
|
|
Interval *result;
|
|
|
|
int year,
|
|
|
|
month;
|
|
|
|
|
|
|
|
if (!PointerIsValid(result = palloc(sizeof(Interval))))
|
|
|
|
elog(ERROR, "Memory allocation failed, can't convert reltime to interval");
|
|
|
|
|
|
|
|
switch (reltime)
|
|
|
|
{
|
|
|
|
case INVALID_RELTIME:
|
|
|
|
INTERVAL_INVALID(*result);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
TMODULO(reltime, year, 31536000);
|
|
|
|
TMODULO(reltime, month, 2592000);
|
|
|
|
|
|
|
|
result->time = reltime;
|
|
|
|
result->month = ((12 * year) + month);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
} /* reltime_interval() */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* mktinterval - creates a time interval with endpoints t1 and t2
|
|
|
|
*/
|
|
|
|
TimeInterval
|
|
|
|
mktinterval(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)
|
|
|
|
*/
|
|
|
|
AbsoluteTime
|
|
|
|
timepl(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)
|
|
|
|
*/
|
|
|
|
AbsoluteTime
|
|
|
|
timemi(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 RelativeTime
|
|
|
|
abstimemi(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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* intinterval - returns 1, iff absolute date is in the interval
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
intinterval(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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalrel - returns relative time corresponding to interval
|
|
|
|
*/
|
|
|
|
RelativeTime
|
|
|
|
tintervalrel(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
|
|
|
|
*/
|
|
|
|
AbsoluteTime
|
|
|
|
timenow()
|
|
|
|
{
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
reltimeeq(RelativeTime t1, RelativeTime t2)
|
|
|
|
{
|
|
|
|
if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
|
|
|
|
return 0;
|
|
|
|
return t1 == t2;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
reltimene(RelativeTime t1, RelativeTime t2)
|
|
|
|
{
|
|
|
|
if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
|
|
|
|
return 0;
|
|
|
|
return t1 != t2;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
reltimelt(RelativeTime t1, RelativeTime t2)
|
|
|
|
{
|
|
|
|
if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
|
|
|
|
return 0;
|
|
|
|
return t1 < t2;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
reltimegt(RelativeTime t1, RelativeTime t2)
|
|
|
|
{
|
|
|
|
if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
|
|
|
|
return 0;
|
|
|
|
return t1 > t2;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
reltimele(RelativeTime t1, RelativeTime t2)
|
|
|
|
{
|
|
|
|
if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
|
|
|
|
return 0;
|
|
|
|
return t1 <= t2;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
reltimege(RelativeTime t1, RelativeTime t2)
|
|
|
|
{
|
|
|
|
if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
|
|
|
|
return 0;
|
|
|
|
return t1 >= t2;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalsame - returns 1, iff interval i1 is same as interval i2
|
|
|
|
* Check begin and end time.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervalsame(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]));
|
|
|
|
} /* tintervalsame() */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervaleq - returns 1, iff interval i1 is equal to interval i2
|
|
|
|
* Check length of intervals.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervaleq(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);
|
|
|
|
} /* tintervaleq() */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalne - returns 1, iff interval i1 is not equal to interval i2
|
|
|
|
* Check length of intervals.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervalne(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);
|
|
|
|
} /* tintervalne() */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervallt - returns TRUE, iff interval i1 is less than interval i2
|
|
|
|
* Check length of intervals.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervallt(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);
|
|
|
|
} /* tintervallt() */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalle - returns TRUE, iff interval i1 is less than or equal to interval i2
|
|
|
|
* Check length of intervals.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervalle(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);
|
|
|
|
} /* tintervalle() */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalgt - returns TRUE, iff interval i1 is less than interval i2
|
|
|
|
* Check length of intervals.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervalgt(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);
|
|
|
|
} /* tintervalgt() */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalge - returns TRUE, iff interval i1 is less than or equal to interval i2
|
|
|
|
* Check length of intervals.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervalge(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);
|
|
|
|
} /* tintervalge() */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalleneq - returns 1, iff length of interval i is equal to
|
|
|
|
* reltime t
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervalleneq(TimeInterval i, RelativeTime t)
|
|
|
|
{
|
|
|
|
RelativeTime rt;
|
|
|
|
|
|
|
|
if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
|
|
|
|
return 0;
|
|
|
|
rt = tintervalrel(i);
|
|
|
|
return rt != INVALID_RELTIME && rt == t;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervallenne - returns 1, iff length of interval i is not equal
|
|
|
|
* to reltime t
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervallenne(TimeInterval i, RelativeTime t)
|
|
|
|
{
|
|
|
|
RelativeTime rt;
|
|
|
|
|
|
|
|
if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
|
|
|
|
return 0;
|
|
|
|
rt = tintervalrel(i);
|
|
|
|
return rt != INVALID_RELTIME && rt != t;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervallenlt - returns 1, iff length of interval i is less than
|
|
|
|
* reltime t
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervallenlt(TimeInterval i, RelativeTime t)
|
|
|
|
{
|
|
|
|
RelativeTime rt;
|
|
|
|
|
|
|
|
if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
|
|
|
|
return 0;
|
|
|
|
rt = tintervalrel(i);
|
|
|
|
return rt != INVALID_RELTIME && rt < t;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervallengt - returns 1, iff length of interval i is greater than
|
|
|
|
* reltime t
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervallengt(TimeInterval i, RelativeTime t)
|
|
|
|
{
|
|
|
|
RelativeTime rt;
|
|
|
|
|
|
|
|
if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
|
|
|
|
return 0;
|
|
|
|
rt = tintervalrel(i);
|
|
|
|
return rt != INVALID_RELTIME && rt > t;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervallenle - returns 1, iff length of interval i is less or equal
|
|
|
|
* than reltime t
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervallenle(TimeInterval i, RelativeTime t)
|
|
|
|
{
|
|
|
|
RelativeTime rt;
|
|
|
|
|
|
|
|
if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
|
|
|
|
return 0;
|
|
|
|
rt = tintervalrel(i);
|
|
|
|
return rt != INVALID_RELTIME && rt <= t;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervallenge - returns 1, iff length of interval i is greater or
|
|
|
|
* equal than reltime t
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervallenge(TimeInterval i, RelativeTime t)
|
|
|
|
{
|
|
|
|
RelativeTime rt;
|
|
|
|
|
|
|
|
if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
|
|
|
|
return 0;
|
|
|
|
rt = tintervalrel(i);
|
|
|
|
return rt != INVALID_RELTIME && rt >= t;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalct - returns 1, iff interval i1 contains interval i2
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervalct(TimeInterval i1, TimeInterval i2)
|
|
|
|
{
|
|
|
|
if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
|
|
|
|
return 0;
|
|
|
|
return (abstimele(i1->data[0], i2->data[0]) &&
|
|
|
|
abstimege(i1->data[1], i2->data[1]));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalov - returns 1, iff interval i1 (partially) overlaps i2
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
tintervalov(TimeInterval i1, TimeInterval i2)
|
|
|
|
{
|
|
|
|
if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
|
|
|
|
return 0;
|
|
|
|
return (!(abstimelt(i1->data[1], i2->data[0]) ||
|
|
|
|
abstimegt(i1->data[0], i2->data[1])));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalstart - returns the start of interval i
|
|
|
|
*/
|
|
|
|
AbsoluteTime
|
|
|
|
tintervalstart(TimeInterval i)
|
|
|
|
{
|
|
|
|
if (i->status == T_INTERVAL_INVAL)
|
|
|
|
return INVALID_ABSTIME;
|
|
|
|
return i->data[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tintervalend - returns the end of interval i
|
|
|
|
*/
|
|
|
|
AbsoluteTime
|
|
|
|
tintervalend(TimeInterval i)
|
|
|
|
{
|
|
|
|
if (i->status == T_INTERVAL_INVAL)
|
|
|
|
return INVALID_ABSTIME;
|
|
|
|
return i->data[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* PRIVATE ROUTINES *
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef NOT_USED
|
|
|
|
/*
|
|
|
|
* isreltime - returns 1, iff datestring is of type reltime
|
|
|
|
* 2, iff datestring is 'invalid time' identifier
|
|
|
|
* 0, iff datestring contains a syntax error
|
|
|
|
* VALID time less or equal +/- `@ 68 years'
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
isreltime(char *str)
|
|
|
|
{
|
|
|
|
struct tm tt,
|
|
|
|
*tm = &tt;
|
|
|
|
double fsec;
|
|
|
|
int dtype;
|
|
|
|
char *field[MAXDATEFIELDS];
|
|
|
|
int nf,
|
|
|
|
ftype[MAXDATEFIELDS];
|
|
|
|
char lowstr[MAXDATELEN + 1];
|
|
|
|
|
|
|
|
if (!PointerIsValid(str))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (strlen(str) > MAXDATELEN)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|
|
|
|
|| (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (dtype)
|
|
|
|
{
|
|
|
|
case (DTK_DELTA):
|
|
|
|
return (abs(tm->tm_year) <= 68) ? 1 : 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case (DTK_INVALID):
|
|
|
|
return 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
} /* isreltime() */
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef NOT_USED
|
|
|
|
int
|
|
|
|
dummyfunc()
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
char c;
|
|
|
|
int i;
|
|
|
|
char unit[UNITMAXLEN];
|
|
|
|
char direction[DIRMAXLEN];
|
|
|
|
int localSign;
|
|
|
|
int localUnitNumber;
|
|
|
|
long localQuantity;
|
|
|
|
|
|
|
|
if (!PointerIsValid(sign))
|
|
|
|
sign = &localSign;
|
|
|
|
|
|
|
|
if (!PointerIsValid(unitnr))
|
|
|
|
unitnr = &localUnitNumber;
|
|
|
|
|
|
|
|
if (!PointerIsValid(quantity))
|
|
|
|
quantity = &localQuantity;
|
|
|
|
|
|
|
|
unit[0] = '\0';
|
|
|
|
direction[0] = '\0';
|
|
|
|
p = timestring;
|
|
|
|
/* skip leading blanks */
|
|
|
|
while ((c = *p) != '\0')
|
|
|
|
{
|
|
|
|
if (c != ' ')
|
|
|
|
break;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Test whether 'invalid time' identifier or not */
|
|
|
|
if (!strncmp(INVALID_RELTIME_STR, p, strlen(INVALID_RELTIME_STR) + 1))
|
|
|
|
return 2; /* correct 'invalid time' identifier found */
|
|
|
|
|
|
|
|
/* handle label of relative time */
|
|
|
|
if (c != RELTIME_LABEL)
|
|
|
|
return 0; /* syntax error */
|
|
|
|
c = *++p;
|
|
|
|
if (c != ' ')
|
|
|
|
return 0; /* syntax error */
|
|
|
|
p++;
|
|
|
|
/* handle the quantity */
|
|
|
|
*quantity = 0;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
c = *p;
|
|
|
|
if (isdigit(c))
|
|
|
|
{
|
|
|
|
*quantity = *quantity * 10 + (c - '0');
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (c == ' ')
|
|
|
|
break; /* correct quantity found */
|
|
|
|
else
|
|
|
|
return 0; /* syntax error */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* handle unit */
|
|
|
|
p++;
|
|
|
|
i = 0;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
c = *p;
|
|
|
|
if (c >= 'a' && c <= 'z' && i <= (UNITMAXLEN - 1))
|
|
|
|
{
|
|
|
|
unit[i] = c;
|
|
|
|
p++;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((c == ' ' || c == '\0')
|
|
|
|
&& correct_unit(unit, unitnr))
|
|
|
|
break; /* correct unit found */
|
|
|
|
else
|
|
|
|
return 0; /* syntax error */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* handle optional direction */
|
|
|
|
if (c == ' ')
|
|
|
|
p++;
|
|
|
|
i = 0;
|
|
|
|
*sign = 1;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
c = *p;
|
|
|
|
if (c >= 'a' && c <= 'z' && i <= (DIRMAXLEN - 1))
|
|
|
|
{
|
|
|
|
direction[i] = c;
|
|
|
|
p++;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((c == ' ' || c == '\0') && i == 0)
|
|
|
|
{
|
|
|
|
*sign = 1;
|
|
|
|
break; /* no direction specified */
|
|
|
|
}
|
|
|
|
if ((c == ' ' || c == '\0') && i != 0)
|
|
|
|
{
|
|
|
|
direction[i] = '\0';
|
|
|
|
correct_dir(direction, sign);
|
|
|
|
break; /* correct direction found */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0; /* syntax error */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* correct_unit - returns 1, iff unit is a correct unit description
|
|
|
|
*
|
|
|
|
* output parameter:
|
|
|
|
* unptr: points to an integer which is the appropriate unit number
|
|
|
|
* (see function isreltime())
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
correct_unit(char *unit, int *unptr)
|
|
|
|
{
|
|
|
|
int j = 0;
|
|
|
|
|
|
|
|
while (j < NUNITS)
|
|
|
|
{
|
|
|
|
if (strncmp(unit, unit_tab[j], strlen(unit_tab[j])) == 0)
|
|
|
|
{
|
|
|
|
*unptr = j;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
return 0; /* invalid unit descriptor */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* correct_dir - returns 1, iff direction is a correct identifier
|
|
|
|
*
|
|
|
|
* output parameter:
|
|
|
|
* signptr: points to -1 if dir corresponds to past tense
|
|
|
|
* else to 1
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
correct_dir(char *direction, int *signptr)
|
|
|
|
{
|
|
|
|
*signptr = 1;
|
|
|
|
if (strncmp(RELTIME_PAST, direction, strlen(RELTIME_PAST) + 1) == 0)
|
|
|
|
{
|
|
|
|
*signptr = -1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0; /* invalid direction descriptor */
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* istinterval - returns 1, iff i_string is a valid interval descr.
|
|
|
|
* 0, iff i_string is NOT a valid interval desc.
|
|
|
|
* 2, iff any time is INVALID_ABSTIME
|
|
|
|
*
|
|
|
|
* output parameter:
|
|
|
|
* i_start, i_end: interval margins
|
|
|
|
*
|
|
|
|
* Time interval:
|
|
|
|
* `[' {` '} `'' <AbsTime> `'' {` '} `'' <AbsTime> `'' {` '} `]'
|
|
|
|
*
|
|
|
|
* OR `Undefined Range' (see also INVALID_INTERVAL_STR)
|
|
|
|
*
|
|
|
|
* where <AbsTime> satisfies the syntax of absolute time.
|
|
|
|
*
|
|
|
|
* e.g. [ ' Jan 18 1902' 'Jan 1 00:00:00 1970']
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
istinterval(char *i_string,
|
|
|
|
AbsoluteTime *i_start,
|
|
|
|
AbsoluteTime *i_end)
|
|
|
|
{
|
|
|
|
char *p,
|
|
|
|
*p1;
|
|
|
|
char c;
|
|
|
|
|
|
|
|
p = i_string;
|
|
|
|
/* skip leading blanks up to '[' */
|
|
|
|
while ((c = *p) != '\0')
|
|
|
|
{
|
|
|
|
if (IsSpace(c))
|
|
|
|
p++;
|
|
|
|
else if (c != '[')
|
|
|
|
return 0; /* syntax error */
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
/* skip leading blanks up to "'" */
|
|
|
|
while ((c = *p) != '\0')
|
|
|
|
{
|
|
|
|
if (IsSpace(c))
|
|
|
|
p++;
|
|
|
|
else if (c != '"')
|
|
|
|
return 0; /* syntax error */
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
if (strncmp(INVALID_INTERVAL_STR, p, strlen(INVALID_INTERVAL_STR)) == 0)
|
|
|
|
return 0; /* undefined range, handled like a syntax
|
|
|
|
* err. */
|
|
|
|
/* search for the end of the first date and change it to a NULL */
|
|
|
|
p1 = p;
|
|
|
|
while ((c = *p1) != '\0')
|
|
|
|
{
|
|
|
|
if (c == '"')
|
|
|
|
{
|
|
|
|
*p1 = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p1++;
|
|
|
|
}
|
|
|
|
/* get the first date */
|
|
|
|
*i_start = nabstimein(p); /* first absolute date */
|
|
|
|
/* rechange NULL at the end of the first date to a "'" */
|
|
|
|
*p1 = '"';
|
|
|
|
p = ++p1;
|
|
|
|
/* skip blanks up to "'", beginning of second date */
|
|
|
|
while ((c = *p) != '\0')
|
|
|
|
{
|
|
|
|
if (IsSpace(c))
|
|
|
|
p++;
|
|
|
|
else if (c != '"')
|
|
|
|
return 0; /* syntax error */
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
/* search for the end of the second date and change it to a NULL */
|
|
|
|
p1 = p;
|
|
|
|
while ((c = *p1) != '\0')
|
|
|
|
{
|
|
|
|
if (c == '"')
|
|
|
|
{
|
|
|
|
*p1 = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p1++;
|
|
|
|
}
|
|
|
|
/* get the second date */
|
|
|
|
*i_end = nabstimein(p); /* second absolute date */
|
|
|
|
/* rechange NULL at the end of the first date to a ''' */
|
|
|
|
*p1 = '"';
|
|
|
|
p = ++p1;
|
|
|
|
/* skip blanks up to ']' */
|
|
|
|
while ((c = *p) != '\0')
|
|
|
|
{
|
|
|
|
if (IsSpace(c))
|
|
|
|
p++;
|
|
|
|
else if (c != ']')
|
|
|
|
return 0; /* syntax error */
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
c = *p;
|
|
|
|
if (c != '\0')
|
|
|
|
return 0; /* syntax error */
|
|
|
|
/* it seems to be a valid interval */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
int32 /* RelativeTime */
|
|
|
|
int4reltime(int32 timevalue)
|
|
|
|
{
|
|
|
|
return timevalue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* timeofday -
|
|
|
|
* returns the current time as a text. similar to timenow() but returns
|
|
|
|
* seconds with more precision (up to microsecs). (I need this to compare
|
|
|
|
* the Wisconsin benchmark with Illustra whose TimeNow() shows current
|
|
|
|
* time with precision up to microsecs.) - ay 3/95
|
|
|
|
*/
|
|
|
|
text *
|
|
|
|
timeofday(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
struct timeval tp;
|
|
|
|
struct timezone tpz;
|
|
|
|
char templ[500];
|
|
|
|
char buf[500];
|
|
|
|
text *tm;
|
|
|
|
int len = 0;
|
|
|
|
|
|
|
|
gettimeofday(&tp, &tpz);
|
|
|
|
strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%d %Y %Z",
|
|
|
|
localtime((time_t *) &tp.tv_sec));
|
|
|
|
sprintf(buf, templ, tp.tv_usec);
|
|
|
|
|
|
|
|
len = VARHDRSZ + strlen(buf);
|
|
|
|
tm = (text *) palloc(len);
|
|
|
|
VARSIZE(tm) = len;
|
|
|
|
strncpy(VARDATA(tm), buf, strlen(buf));
|
|
|
|
return tm;
|
|
|
|
}
|