Integrate src/timezone library for all platforms. There is more we can

and should do now that we control our own destiny for timezone handling,
but this commit gets the bulk of the picayune diffs in place.
Magnus Hagander and Tom Lane.
This commit is contained in:
Tom Lane 2004-05-21 05:08:06 +00:00
parent 260b513fc3
commit 63bd0db121
52 changed files with 1342 additions and 8101 deletions

2
configure vendored
View File

@ -12014,7 +12014,7 @@ LIBOBJS="$LIBOBJS open.$ac_objext"
LIBOBJS="$LIBOBJS rand.$ac_objext" ;;
esac
# Win32 can't to rename or unlink on an open file
# Win32 can't do rename or unlink on an open file
case $host_os in mingw*|cygwin*)
LIBOBJS="$LIBOBJS dirmod.$ac_objext" ;;
esac

View File

@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script.
dnl $PostgreSQL: pgsql/configure.in,v 1.355 2004/05/20 23:49:41 pgsql Exp $
dnl $PostgreSQL: pgsql/configure.in,v 1.356 2004/05/21 05:07:54 tgl Exp $
dnl
dnl Developers, please strive to achieve this order:
dnl
@ -895,7 +895,7 @@ AC_LIBOBJ(open)
AC_LIBOBJ(rand) ;;
esac
# Win32 can't to rename or unlink on an open file
# Win32 can't do rename or unlink on an open file
case $host_os in mingw*|cygwin*)
AC_LIBOBJ(dirmod) ;;
esac

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/regress.sgml,v 1.39 2004/03/15 16:11:42 momjian Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/regress.sgml,v 1.40 2004/05/21 05:07:55 tgl Exp $ -->
<chapter id="regress">
<title id="regress-title">Regression Tests</title>
@ -378,20 +378,19 @@ testname/platformpattern=comparisonfilename
</para>
<para>
For example: some systems using older time zone libraries fail to apply
daylight-saving corrections to dates before 1970, causing
pre-1970 <acronym>PDT</acronym> times to be displayed in <acronym>PST</acronym> instead. This causes a
few differences in the <filename>horology</> regression test.
For example: some systems interpret very small floating-point values
as zero, rather than reporting an underflow error. This causes a
few differences in the <filename>float8</> regression test.
Therefore, we provide a variant comparison file,
<filename>horology-no-DST-before-1970.out</filename>, which includes
<filename>float8-small-is-zero.out</filename>, which includes
the results to be expected on these systems. To silence the bogus
<quote>failure</quote> message on <systemitem>HPUX</systemitem> platforms,
<filename>resultmap</filename> includes
<quote>failure</quote> message on <systemitem>OpenBSD</systemitem>
platforms, <filename>resultmap</filename> includes
<programlisting>
horology/.*-hpux=horology-no-DST-before-1970
float8/i.86-.*-openbsd=float8-small-is-zero
</programlisting>
which will trigger on any machine for which the output of
<command>config.guess</command> includes <literal>-hpux</literal>.
<command>config.guess</command> matches <literal>i.86-.*-openbsd</literal>.
Other lines
in <filename>resultmap</> select the variant comparison file for other
platforms where it's appropriate.

View File

@ -1,5 +1,5 @@
# -*-makefile-*-
# $PostgreSQL: pgsql/src/Makefile.global.in,v 1.184 2004/05/14 00:03:07 momjian Exp $
# $PostgreSQL: pgsql/src/Makefile.global.in,v 1.185 2004/05/21 05:07:55 tgl Exp $
#------------------------------------------------------------------------------
# All PostgreSQL makefiles include this file and use the variables it sets,
@ -147,8 +147,6 @@ TK_LIBS = @TK_LIBS@
TK_LIB_SPEC = @TK_LIB_SPEC@
TK_XINCLUDES = @TK_XINCLUDES@
USE_PGTZ = @USE_PGTZ@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@

View File

@ -4,7 +4,7 @@
#
# Copyright (c) 1994, Regents of the University of California
#
# $PostgreSQL: pgsql/src/backend/Makefile,v 1.99 2004/04/30 16:08:01 momjian Exp $
# $PostgreSQL: pgsql/src/backend/Makefile,v 1.100 2004/05/21 05:07:55 tgl Exp $
#
#-------------------------------------------------------------------------
@ -14,11 +14,7 @@ include $(top_builddir)/src/Makefile.global
DIRS := access bootstrap catalog parser commands executor lib libpq \
main nodes optimizer port postmaster regex rewrite \
storage tcop utils
ifeq ($(USE_PGTZ), yes)
DIRS+= $(top_builddir)/src/timezone
endif
storage tcop utils $(top_builddir)/src/timezone
OBJS := $(DIRS:%=%/SUBSYS.o)

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.165 2004/04/05 03:11:39 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.166 2004/05/21 05:07:56 tgl Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
@ -1828,7 +1828,7 @@ xact_desc(char *buf, uint8 xl_info, char *rec)
if (info == XLOG_XACT_COMMIT)
{
xl_xact_commit *xlrec = (xl_xact_commit *) rec;
struct tm *tm = localtime(&xlrec->xtime);
struct pg_tm *tm = pg_localtime(&xlrec->xtime);
sprintf(buf + strlen(buf), "commit: %04u-%02u-%02u %02u:%02u:%02u",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
@ -1838,7 +1838,7 @@ xact_desc(char *buf, uint8 xl_info, char *rec)
else if (info == XLOG_XACT_ABORT)
{
xl_xact_abort *xlrec = (xl_xact_abort *) rec;
struct tm *tm = localtime(&xlrec->xtime);
struct pg_tm *tm = pg_localtime(&xlrec->xtime);
sprintf(buf + strlen(buf), "abort: %04u-%02u-%02u %02u:%02u:%02u",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.140 2004/05/07 00:24:57 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.141 2004/05/21 05:07:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -18,7 +18,6 @@
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "access/clog.h"
#include "access/transam.h"
@ -2764,9 +2763,9 @@ str_time(time_t tnow)
{
static char buf[128];
strftime(buf, sizeof(buf),
pg_strftime(buf, sizeof(buf),
"%Y-%m-%d %H:%M:%S %Z",
localtime(&tnow));
pg_localtime(&tnow));
return buf;
}

View File

@ -9,14 +9,13 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.66 2004/05/05 04:48:45 tgl Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.67 2004/05/21 05:07:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <time.h>
#include <unistd.h>
#include "access/attnum.h"
@ -39,6 +38,7 @@
#include "nodes/parsenodes.h"
#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
#include "pgtime.h"
#include "rewrite/prs2lock.h"
#include "storage/block.h"
#include "storage/fd.h"

View File

@ -9,14 +9,12 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootscanner.l,v 1.33 2004/02/24 22:06:32 tgl Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootscanner.l,v 1.34 2004/05/21 05:07:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <time.h>
#include "access/attnum.h"
#include "access/htup.h"
#include "access/itup.h"
@ -31,6 +29,7 @@
#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
#include "parser/scansup.h"
#include "pgtime.h"
#include "rewrite/prs2lock.h"
#include "storage/block.h"
#include "storage/fd.h"

View File

@ -8,14 +8,13 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.178 2004/04/01 21:28:43 tgl Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.179 2004/05/21 05:07:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <setjmp.h>
#ifdef HAVE_GETOPT_H
@ -34,6 +33,7 @@
#include "executor/executor.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgtime.h"
#include "storage/freespace.h"
#include "storage/ipc.h"
#include "storage/pg_shmem.h"
@ -392,8 +392,8 @@ BootstrapMain(int argc, char *argv[])
if (IsUnderPostmaster)
{
#ifdef EXEC_BACKEND
read_nondefault_variables();
read_backend_variables(backendID,NULL);
read_nondefault_variables();
SSDataBaseInit(xlogop);
#endif
@ -401,6 +401,9 @@ BootstrapMain(int argc, char *argv[])
else
ProcessConfigFile(PGC_POSTMASTER);
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize();
if (IsUnderPostmaster)
{
/*

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.94 2004/05/07 00:24:57 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.95 2004/05/21 05:07:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -17,30 +17,19 @@
#include "postgres.h"
#include <ctype.h>
#include <time.h>
#include "access/xact.h"
#include "catalog/pg_shadow.h"
#include "commands/variable.h"
#include "miscadmin.h"
#include "parser/scansup.h"
#include "pgtime.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
#include "mb/pg_wchar.h"
/*
* Some systems have tzname[] but don't declare it in <time.h>. Use this
* to duplicate the test in AC_STRUCT_TIMEZONE.
*/
#ifdef HAVE_TZNAME
#ifndef tzname /* For SGI. */
extern char *tzname[];
#endif
#endif
/*
* DATESTYLE
*/
@ -237,149 +226,6 @@ assign_datestyle(const char *value, bool doit, GucSource source)
* TIMEZONE
*/
/*
* Storage for TZ env var is allocated with an arbitrary size of 64 bytes.
*/
#define TZBUF_LEN 64
static char tzbuf[TZBUF_LEN];
/*
* First time through, we remember the original environment TZ value, if any.
*/
static bool have_saved_tz = false;
static char orig_tzbuf[TZBUF_LEN];
/*
* Convenience subroutine for assigning the value of TZ
*/
static void
set_tz(const char *tz)
{
strcpy(tzbuf, "TZ=");
strncpy(tzbuf + 3, tz, sizeof(tzbuf) - 4);
if (putenv(tzbuf) != 0) /* shouldn't happen? */
elog(LOG, "could not set TZ environment variable");
tzset();
}
/*
* Remove any value of TZ we have established
*
* Note: this leaves us with *no* value of TZ in the environment, and
* is therefore only appropriate for reverting to that state, not for
* reverting to a state where TZ was set to something else.
*/
static void
clear_tz(void)
{
/*
* unsetenv() works fine, but is BSD, not POSIX, and is not available
* under Solaris, among others. Apparently putenv() called as below
* clears the process-specific environment variables. Other
* reasonable arguments to putenv() (e.g. "TZ=", "TZ", "") result in a
* core dump (under Linux anyway). - thomas 1998-01-26
*/
if (tzbuf[0] == 'T')
{
strcpy(tzbuf, "=");
if (putenv(tzbuf) != 0)
elog(LOG, "could not clear TZ environment variable");
tzset();
}
}
/*
* Check whether tzset() succeeded
*
* Unfortunately, tzset doesn't offer any well-defined way to detect that the
* value of TZ was bad. Often it will just select UTC (GMT) as the effective
* timezone. We use the following heuristics:
*
* If tzname[1] is a nonempty string, *or* the global timezone variable is
* not zero, then tzset must have recognized the TZ value as something
* different from UTC. Return true.
*
* Otherwise, check to see if the TZ name is a known spelling of "UTC"
* (ie, appears in our internal tables as a timezone equivalent to UTC).
* If so, accept it.
*
* This will reject nonstandard spellings of UTC unless tzset() chose to
* set tzname[1] as well as tzname[0]. The glibc version of tzset() will
* do so, but on other systems we may be tightening the spec a little.
*
* Another problem is that on some platforms (eg HPUX), if tzset thinks the
* input is bogus then it will adopt the system default timezone, which we
* really can't tell is not the intended translation of the input.
*
* Still, it beats failing to detect bad TZ names at all, and a silent
* failure mode of adopting the system-wide default is much better than
* a silent failure mode of adopting UTC.
*
* NB: this must NOT ereport(ERROR). The caller must get control back so that
* it can restore the old value of TZ if we don't like the new one.
*/
static bool
tzset_succeeded(const char *tz)
{
char *tztmp;
int tzval;
/*
* Check first set of heuristics to say that tzset definitely worked.
*/
#ifdef HAVE_TZNAME
if (tzname[1] && tzname[1][0] != '\0')
return true;
#endif
if (TIMEZONE_GLOBAL != 0)
return true;
/*
* Check for known spellings of "UTC". Note we must downcase the
* input before passing it to DecodePosixTimezone().
*/
tztmp = downcase_truncate_identifier(tz, strlen(tz), false);
if (DecodePosixTimezone(tztmp, &tzval) == 0)
if (tzval == 0)
return true;
return false;
}
/*
* Check whether timezone is acceptable.
*
* What we are doing here is checking for leap-second-aware timekeeping.
* We need to reject such TZ settings because they'll wreak havoc with our
* date/time arithmetic.
*
* NB: this must NOT ereport(ERROR). The caller must get control back so that
* it can restore the old value of TZ if we don't like the new one.
*/
static bool
tz_acceptable(void)
{
struct tm tt;
time_t time2000;
/*
* To detect leap-second timekeeping, compute the time_t value for
* local midnight, 2000-01-01. Insist that this be a multiple of 60;
* any partial-minute offset has to be due to leap seconds.
*/
MemSet(&tt, 0, sizeof(tt));
tt.tm_year = 100;
tt.tm_mon = 0;
tt.tm_mday = 1;
tt.tm_isdst = -1;
time2000 = mktime(&tt);
if ((time2000 % 60) != 0)
return false;
return true;
}
/*
* assign_timezone: GUC assign_hook for timezone
*/
@ -390,21 +236,6 @@ assign_timezone(const char *value, bool doit, GucSource source)
char *endptr;
double hours;
/*
* On first call, see if there is a TZ in the original environment.
* Save that value permanently.
*/
if (!have_saved_tz)
{
char *orig_tz = getenv("TZ");
if (orig_tz)
StrNCpy(orig_tzbuf, orig_tz, sizeof(orig_tzbuf));
else
orig_tzbuf[0] = '\0';
have_saved_tz = true;
}
/*
* Check for INTERVAL 'foo'
*/
@ -476,36 +307,21 @@ assign_timezone(const char *value, bool doit, GucSource source)
{
/*
* UNKNOWN is the value shown as the "default" for TimeZone in
* guc.c. We interpret it as meaning the original TZ
* inherited from the environment. Note that if there is an
* original TZ setting, we will return that rather than
* guc.c. We interpret it as being a complete no-op; we don't
* change the timezone setting. Note that if there is a known
* timezone setting, we will return that name rather than
* UNKNOWN as the canonical spelling.
*
* During GUC initialization, since the timezone library isn't
* set up yet, pg_get_current_timezone will return NULL and we
* will leave the setting as UNKNOWN. If this isn't overridden
* from the config file then pg_timezone_initialize() will
* eventually select a default value from the environment.
*/
if (doit)
{
bool ok;
const char *curzone = pg_get_current_timezone();
/* Revert to original setting of TZ, whatever it was */
if (orig_tzbuf[0])
{
set_tz(orig_tzbuf);
ok = tzset_succeeded(orig_tzbuf) && tz_acceptable();
}
else
{
clear_tz();
ok = tz_acceptable();
}
if (ok)
HasCTZSet = false;
else
{
/* Bogus, so force UTC (equivalent to INTERVAL 0) */
CTimeZone = 0;
HasCTZSet = true;
}
}
if (curzone)
value = curzone;
}
else
{
@ -514,22 +330,22 @@ assign_timezone(const char *value, bool doit, GucSource source)
*
* We have to actually apply the change before we can have any
* hope of checking it. So, save the old value in case we
* have to back out. Note that it's possible the old setting
* is in tzbuf, so we'd better copy it.
* have to back out. We have to copy since pg_get_current_timezone
* returns a pointer to its static state.
*/
char save_tzbuf[TZBUF_LEN];
const char *cur_tz;
char *save_tz;
bool known,
acceptable;
save_tz = getenv("TZ");
if (save_tz)
StrNCpy(save_tzbuf, save_tz, sizeof(save_tzbuf));
cur_tz = pg_get_current_timezone();
if (cur_tz)
save_tz = pstrdup(cur_tz);
else
save_tz = NULL;
set_tz(value);
known = tzset_succeeded(value);
acceptable = tz_acceptable();
known = pg_tzset(value);
acceptable = known ? tz_acceptable() : false;
if (doit && known && acceptable)
{
@ -544,9 +360,9 @@ assign_timezone(const char *value, bool doit, GucSource source)
* a fixed offset, we still are.
*/
if (save_tz)
set_tz(save_tzbuf);
else
clear_tz();
pg_tzset(save_tz);
else /* TZ library not initialized yet */
select_default_timezone();
/* Complain if it was bad */
if (!known)
{
@ -578,17 +394,16 @@ assign_timezone(const char *value, bool doit, GucSource source)
/*
* Prepare the canonical string to return. GUC wants it malloc'd.
*/
result = (char *) malloc(sizeof(tzbuf));
if (HasCTZSet)
{
result = (char *) malloc(64);
if (!result)
return NULL;
if (HasCTZSet)
snprintf(result, sizeof(tzbuf), "%.5f",
snprintf(result, 64, "%.5f",
(double) (-CTimeZone) / 3600.0);
else if (tzbuf[0] == 'T')
strcpy(result, tzbuf + 3);
}
else
strcpy(result, "UNKNOWN");
result = strdup(value);
return result;
}
@ -599,7 +414,7 @@ assign_timezone(const char *value, bool doit, GucSource source)
const char *
show_timezone(void)
{
char *tzn;
const char *tzn;
if (HasCTZSet)
{
@ -612,7 +427,7 @@ show_timezone(void)
IntervalPGetDatum(&interval)));
}
else
tzn = getenv("TZ");
tzn = pg_get_current_timezone();
if (tzn != NULL)
return tzn;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_main.c,v 1.43 2004/01/23 23:54:21 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_main.c,v 1.44 2004/05/21 05:07:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -24,7 +24,6 @@
#include "postgres.h"
#include <time.h>
#include <math.h>
#include "optimizer/geqo.h"
@ -32,6 +31,7 @@
#include "optimizer/geqo_mutation.h"
#include "optimizer/geqo_pool.h"
#include "optimizer/geqo_selection.h"
#include "pgtime.h"
/*

View File

@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.392 2004/05/19 19:11:25 momjian Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.393 2004/05/21 05:07:57 tgl Exp $
*
* NOTES
*
@ -66,11 +66,9 @@
#include <sys/wait.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@ -99,6 +97,7 @@
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "nodes/nodes.h"
#include "pgtime.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/pg_shmem.h"
@ -636,6 +635,10 @@ PostmasterMain(int argc, char *argv[])
SetDataDir(potential_DataDir);
ProcessConfigFile(PGC_POSTMASTER);
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize();
#ifdef EXEC_BACKEND
write_nondefault_variables(PGC_POSTMASTER);
#endif
@ -906,7 +909,7 @@ PostmasterMain(int argc, char *argv[])
{
time_t now = time(NULL);
(void) localtime(&now);
(void) pg_localtime(&now);
}
/*
@ -2704,8 +2707,8 @@ SubPostmasterMain(int argc, char* argv[])
DataDir = strdup(argv[argc++]);
/* Read in file-based context */
read_nondefault_variables();
read_backend_variables(backendID,&port);
read_nondefault_variables();
/* Remaining initialization */
pgstat_init_forkexec_backend();
@ -3356,6 +3359,8 @@ write_backend_variables(Port *port)
write_var(debug_flag,fp);
write_var(PostmasterPid,fp);
fwrite((void *)my_exec_path, MAXPGPATH, 1, fp);
/* Release file */
if (FreeFile(fp))
{
@ -3418,6 +3423,8 @@ read_backend_variables(unsigned long id, Port *port)
read_var(debug_flag,fp);
read_var(PostmasterPid,fp);
fread((void *)my_exec_path, MAXPGPATH, 1, fp);
/* Release file */
FreeFile(fp);
if (unlink(filename) != 0)

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.412 2004/05/19 21:17:33 momjian Exp $
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.413 2004/05/21 05:07:58 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@ -21,8 +21,6 @@
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <errno.h>
@ -48,6 +46,7 @@
#include "optimizer/planner.h"
#include "parser/analyze.h"
#include "parser/parser.h"
#include "pgtime.h"
#include "rewrite/rewriteHandler.h"
#include "storage/freespace.h"
#include "storage/ipc.h"
@ -2566,6 +2565,9 @@ PostgresMain(int argc, char *argv[], const char *username)
} else
ProcessConfigFile(PGC_POSTMASTER);
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize();
/*
* Set up signal handlers and masks.
*

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.96 2004/05/07 00:24:58 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.97 2004/05/21 05:08:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -17,13 +17,13 @@
#include <ctype.h>
#include <limits.h>
#include <time.h>
#include <float.h>
#include "access/hash.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "parser/scansup.h"
#include "pgtime.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/nabstime.h"
@ -38,10 +38,10 @@
#endif
static int time2tm(TimeADT time, struct tm * tm, fsec_t *fsec);
static int timetz2tm(TimeTzADT *time, struct tm * tm, fsec_t *fsec, int *tzp);
static int tm2time(struct tm * tm, fsec_t fsec, TimeADT *result);
static int tm2timetz(struct tm * tm, fsec_t fsec, int tz, TimeTzADT *result);
static int time2tm(TimeADT time, struct pg_tm * tm, fsec_t *fsec);
static int timetz2tm(TimeTzADT *time, struct pg_tm * tm, fsec_t *fsec, int *tzp);
static int tm2time(struct pg_tm * tm, fsec_t fsec, TimeADT *result);
static int tm2timetz(struct pg_tm * tm, fsec_t fsec, int tz, TimeTzADT *result);
static void AdjustTimeForTypmod(TimeADT *time, int32 typmod);
/*****************************************************************************
@ -58,7 +58,7 @@ date_in(PG_FUNCTION_ARGS)
char *str = PG_GETARG_CSTRING(0);
DateADT date;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int tzp;
int dtype;
@ -112,7 +112,7 @@ date_out(PG_FUNCTION_ARGS)
{
DateADT date = PG_GETARG_DATEADT(0);
char *result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
char buf[MAXDATELEN + 1];
@ -293,7 +293,7 @@ static TimestampTz
date2timestamptz(DateADT dateVal)
{
TimestampTz result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
j2date(dateVal + POSTGRES_EPOCH_JDATE,
@ -733,7 +733,7 @@ timestamp_date(PG_FUNCTION_ARGS)
{
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
DateADT result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
@ -774,7 +774,7 @@ timestamptz_date(PG_FUNCTION_ARGS)
{
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
DateADT result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
int tz;
@ -802,7 +802,7 @@ abstime_date(PG_FUNCTION_ARGS)
{
AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
DateADT result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int tz;
@ -903,7 +903,7 @@ time_in(PG_FUNCTION_ARGS)
int32 typmod = PG_GETARG_INT32(2);
TimeADT result;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int tz;
int nf;
@ -932,7 +932,7 @@ time_in(PG_FUNCTION_ARGS)
* Convert a tm structure to a time data type.
*/
static int
tm2time(struct tm * tm, fsec_t fsec, TimeADT *result)
tm2time(struct pg_tm * tm, fsec_t fsec, TimeADT *result)
{
#ifdef HAVE_INT64_TIMESTAMP
*result = ((((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec)
@ -949,7 +949,7 @@ tm2time(struct tm * tm, fsec_t fsec, TimeADT *result)
* local time zone. If out of this range, leave as GMT. - tgl 97/05/27
*/
static int
time2tm(TimeADT time, struct tm * tm, fsec_t *fsec)
time2tm(TimeADT time, struct pg_tm * tm, fsec_t *fsec)
{
#ifdef HAVE_INT64_TIMESTAMP
tm->tm_hour = (time / INT64CONST(3600000000));
@ -977,7 +977,7 @@ time_out(PG_FUNCTION_ARGS)
{
TimeADT time = PG_GETARG_TIMEADT(0);
char *result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
char buf[MAXDATELEN + 1];
@ -1338,7 +1338,7 @@ timestamp_time(PG_FUNCTION_ARGS)
{
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
TimeADT result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
@ -1373,7 +1373,7 @@ timestamptz_time(PG_FUNCTION_ARGS)
{
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
TimeADT result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int tz;
fsec_t fsec;
@ -1641,7 +1641,7 @@ time_part(PG_FUNCTION_ARGS)
if (type == UNITS)
{
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
time2tm(time, tm, &fsec);
@ -1731,7 +1731,7 @@ time_part(PG_FUNCTION_ARGS)
* Convert a tm structure to a time data type.
*/
static int
tm2timetz(struct tm * tm, fsec_t fsec, int tz, TimeTzADT *result)
tm2timetz(struct pg_tm * tm, fsec_t fsec, int tz, TimeTzADT *result)
{
#ifdef HAVE_INT64_TIMESTAMP
result->time = ((((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec)
@ -1755,7 +1755,7 @@ timetz_in(PG_FUNCTION_ARGS)
int32 typmod = PG_GETARG_INT32(2);
TimeTzADT *result;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int tz;
int nf;
@ -1786,7 +1786,7 @@ timetz_out(PG_FUNCTION_ARGS)
{
TimeTzADT *time = PG_GETARG_TIMETZADT_P(0);
char *result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
int tz;
@ -1844,7 +1844,7 @@ timetz_send(PG_FUNCTION_ARGS)
* Convert TIME WITH TIME ZONE data type to POSIX time structure.
*/
static int
timetz2tm(TimeTzADT *time, struct tm * tm, fsec_t *fsec, int *tzp)
timetz2tm(TimeTzADT *time, struct pg_tm * tm, fsec_t *fsec, int *tzp)
{
#ifdef HAVE_INT64_TIMESTAMP
int64 trem = time->time;
@ -2237,7 +2237,7 @@ time_timetz(PG_FUNCTION_ARGS)
{
TimeADT time = PG_GETARG_TIMEADT(0);
TimeTzADT *result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
int tz;
@ -2263,7 +2263,7 @@ timestamptz_timetz(PG_FUNCTION_ARGS)
{
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
TimeTzADT *result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int tz;
fsec_t fsec;
@ -2394,7 +2394,7 @@ timetz_part(PG_FUNCTION_ARGS)
double dummy;
int tz;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
timetz2tm(time, tm, &fsec, &tz);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.127 2004/05/07 00:24:58 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.128 2004/05/21 05:08:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -27,15 +27,16 @@
static int DecodeNumber(int flen, char *field, bool haveTextMonth,
int fmask, int *tmask,
struct tm * tm, fsec_t *fsec, int *is2digits);
struct pg_tm * tm, fsec_t *fsec, int *is2digits);
static int DecodeNumberField(int len, char *str,
int fmask, int *tmask,
struct tm * tm, fsec_t *fsec, int *is2digits);
struct pg_tm * tm, fsec_t *fsec, int *is2digits);
static int DecodeTime(char *str, int fmask, int *tmask,
struct tm * tm, fsec_t *fsec);
struct pg_tm * tm, fsec_t *fsec);
static int DecodeTimezone(char *str, int *tzp);
static int DecodePosixTimezone(char *str, int *tzp);
static datetkn *datebsearch(char *key, datetkn *base, unsigned int nel);
static int DecodeDate(char *str, int fmask, int *tmask, struct tm * tm);
static int DecodeDate(char *str, int fmask, int *tmask, struct pg_tm * tm);
static void TrimTrailingZeros(char *str);
@ -913,7 +914,7 @@ ParseDateTime(const char *timestr, char *lowstr,
*/
int
DecodeDateTime(char **field, int *ftype, int nf,
int *dtype, struct tm * tm, fsec_t *fsec, int *tzp)
int *dtype, struct pg_tm * tm, fsec_t *fsec, int *tzp)
{
int fmask = 0,
tmask,
@ -1566,9 +1567,9 @@ DecodeDateTime(char **field, int *ftype, int nf,
/* DetermineLocalTimeZone()
*
* Given a struct tm in which tm_year, tm_mon, tm_mday, tm_hour, tm_min, and
* Given a struct pg_tm in which tm_year, tm_mon, tm_mday, tm_hour, tm_min, and
* tm_sec fields are set, attempt to determine the applicable local zone
* (ie, regular or daylight-savings time) at that time. Set the struct tm's
* (ie, regular or daylight-savings time) at that time. Set the struct pg_tm's
* tm_isdst field accordingly, and return the actual timezone offset.
*
* Note: this subroutine exists because mktime() has such a spectacular
@ -1577,7 +1578,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
* mktime() anywhere else.
*/
int
DetermineLocalTimeZone(struct tm * tm)
DetermineLocalTimeZone(struct pg_tm * tm)
{
int tz;
@ -1600,7 +1601,7 @@ DetermineLocalTimeZone(struct tm * tm)
delta1,
delta2;
time_t mytime;
struct tm *tx;
struct pg_tm *tx;
day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - UNIX_EPOCH_JDATE;
mysec = tm->tm_sec + (tm->tm_min + (day * 24 + tm->tm_hour) * 60) * 60;
@ -1610,7 +1611,7 @@ DetermineLocalTimeZone(struct tm * tm)
* Use localtime to convert that time_t to broken-down time,
* and reassemble to get a representation of local time.
*/
tx = localtime(&mytime);
tx = pg_localtime(&mytime);
if (!tx)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
@ -1624,7 +1625,6 @@ DetermineLocalTimeZone(struct tm * tm)
* computable as mysec - locsec.
*/
delta1 = mysec - locsec;
/*
* However, if that GMT time and the local time we are
* actually interested in are on opposite sides of a
@ -1635,7 +1635,7 @@ DetermineLocalTimeZone(struct tm * tm)
*/
mysec += delta1;
mytime = (time_t) mysec;
tx = localtime(&mytime);
tx = pg_localtime(&mytime);
if (!tx)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
@ -1660,7 +1660,7 @@ DetermineLocalTimeZone(struct tm * tm)
{
mysec += (delta2 - delta1);
mytime = (time_t) mysec;
tx = localtime(&mytime);
tx = pg_localtime(&mytime);
if (!tx)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
@ -1698,7 +1698,7 @@ DetermineLocalTimeZone(struct tm * tm)
*/
int
DecodeTimeOnly(char **field, int *ftype, int nf,
int *dtype, struct tm * tm, fsec_t *fsec, int *tzp)
int *dtype, struct pg_tm * tm, fsec_t *fsec, int *tzp)
{
int fmask = 0,
tmask,
@ -2201,7 +2201,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
/* timezone not specified? then find local timezone if possible */
if ((tzp != NULL) && (!(fmask & DTK_M(TZ))))
{
struct tm tt,
struct pg_tm tt,
*tmp = &tt;
/*
@ -2236,7 +2236,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
* Insist on a complete set of fields.
*/
static int
DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
DecodeDate(char *str, int fmask, int *tmask, struct pg_tm * tm)
{
fsec_t fsec;
int nf = 0;
@ -2394,7 +2394,7 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
* can be used to represent time spans.
*/
static int
DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
DecodeTime(char *str, int fmask, int *tmask, struct pg_tm * tm, fsec_t *fsec)
{
char *cp;
@ -2461,7 +2461,7 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
*/
static int
DecodeNumber(int flen, char *str, bool haveTextMonth, int fmask,
int *tmask, struct tm * tm, fsec_t *fsec, int *is2digits)
int *tmask, struct pg_tm * tm, fsec_t *fsec, int *is2digits)
{
int val;
char *cp;
@ -2651,7 +2651,7 @@ DecodeNumber(int flen, char *str, bool haveTextMonth, int fmask,
*/
static int
DecodeNumberField(int len, char *str, int fmask,
int *tmask, struct tm * tm, fsec_t *fsec, int *is2digits)
int *tmask, struct pg_tm * tm, fsec_t *fsec, int *is2digits)
{
char *cp;
@ -2797,10 +2797,8 @@ DecodeTimezone(char *str, int *tzp)
* - thomas 2000-03-15
*
* Return 0 if okay (and set *tzp), a DTERR code if not okay.
*
* NB: this must *not* ereport on failure; see commands/variable.c.
*/
int
static int
DecodePosixTimezone(char *str, int *tzp)
{
int val,
@ -2911,7 +2909,7 @@ DecodeSpecial(int field, char *lowtoken, int *val)
* preceding an hh:mm:ss field. - thomas 1998-04-30
*/
int
DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fsec_t *fsec)
DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm, fsec_t *fsec)
{
int is_before = FALSE;
char *cp;
@ -3365,7 +3363,7 @@ datebsearch(char *key, datetkn *base, unsigned int nel)
* Encode date as local time.
*/
int
EncodeDateOnly(struct tm * tm, int style, char *str)
EncodeDateOnly(struct pg_tm * tm, int style, char *str)
{
if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
return -1;
@ -3425,7 +3423,7 @@ EncodeDateOnly(struct tm * tm, int style, char *str)
* Encode time fields only.
*/
int
EncodeTimeOnly(struct tm * tm, fsec_t fsec, int *tzp, int style, char *str)
EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, int *tzp, int style, char *str)
{
if ((tm->tm_hour < 0) || (tm->tm_hour > 24))
return -1;
@ -3478,7 +3476,7 @@ EncodeTimeOnly(struct tm * tm, fsec_t fsec, int *tzp, int style, char *str)
* European - dd/mm/yyyy
*/
int
EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str)
EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str)
{
int day,
hour,
@ -3709,7 +3707,7 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
* - thomas 1998-04-30
*/
int
EncodeInterval(struct tm * tm, fsec_t fsec, int style, char *str)
EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
{
int is_before = FALSE;
int is_nonzero = FALSE;

View File

@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------
* formatting.c
*
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.74 2004/05/07 00:24:58 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.75 2004/05/21 05:08:02 tgl Exp $
*
*
* Portions Copyright (c) 1999-2003, PostgreSQL Global Development Group
@ -70,7 +70,6 @@
#include "postgres.h"
#include <ctype.h>
#include <sys/time.h>
#include <unistd.h>
#include <math.h>
#include <float.h>
@ -410,7 +409,7 @@ typedef struct
*/
typedef struct TmToChar
{
struct tm tm; /* classic 'tm' struct */
struct pg_tm tm; /* classic 'tm' struct */
fsec_t fsec; /* fractional seconds */
char *tzn; /* timezone */
} TmToChar;
@ -897,7 +896,7 @@ static int dch_global(int arg, char *inout, int suf, int flag, FormatNode *node,
static int dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data);
static int dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data);
static void do_to_timestamp(text *date_txt, text *fmt,
struct tm *tm, fsec_t *fsec);
struct pg_tm *tm, fsec_t *fsec);
static char *fill_str(char *str, int c, int max);
static FormatNode *NUM_cache(int len, NUMDesc *Num, char *pars_str, bool *shouldFree);
static char *int_to_roman(int number);
@ -1695,7 +1694,7 @@ static int
dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
{
char *p_inout = inout;
struct tm *tm = NULL;
struct pg_tm *tm = NULL;
TmFromChar *tmfc = NULL;
TmToChar *tmtc = NULL;
@ -2057,7 +2056,7 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
*p_inout;
int i,
len;
struct tm *tm = NULL;
struct pg_tm *tm = NULL;
TmFromChar *tmfc = NULL;
TmToChar *tmtc = NULL;
@ -2768,7 +2767,7 @@ static text *
datetime_to_char_body(TmToChar *tmtc, text *fmt)
{
FormatNode *format;
struct tm *tm = NULL;
struct pg_tm *tm = NULL;
char *fmt_str,
*result;
bool incache;
@ -2962,7 +2961,7 @@ to_timestamp(PG_FUNCTION_ARGS)
text *fmt = PG_GETARG_TEXT_P(1);
Timestamp result;
int tz;
struct tm tm;
struct pg_tm tm;
fsec_t fsec;
do_to_timestamp(date_txt, fmt, &tm, &fsec);
@ -2988,7 +2987,7 @@ to_date(PG_FUNCTION_ARGS)
text *date_txt = PG_GETARG_TEXT_P(0);
text *fmt = PG_GETARG_TEXT_P(1);
DateADT result;
struct tm tm;
struct pg_tm tm;
fsec_t fsec;
do_to_timestamp(date_txt, fmt, &tm, &fsec);
@ -3001,12 +3000,12 @@ to_date(PG_FUNCTION_ARGS)
/*
* do_to_timestamp: shared code for to_timestamp and to_date
*
* Parse the 'date_txt' according to 'fmt', return results as a struct tm
* Parse the 'date_txt' according to 'fmt', return results as a struct pg_tm
* and fractional seconds.
*/
static void
do_to_timestamp(text *date_txt, text *fmt,
struct tm *tm, fsec_t *fsec)
struct pg_tm *tm, fsec_t *fsec)
{
FormatNode *format;
TmFromChar tmfc;

View File

@ -8,14 +8,13 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.32 2003/11/29 19:51:58 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.33 2004/05/21 05:08:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <sys/file.h>
#include <time.h>
#include "commands/dbcommands.h"
#include "miscadmin.h"

View File

@ -10,21 +10,20 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.120 2004/05/05 17:28:46 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.121 2004/05/21 05:08:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <ctype.h>
#include <time.h>
#include <sys/time.h>
#include <float.h>
#include <limits.h>
#include "access/xact.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "pgtime.h"
#include "utils/builtins.h"
@ -76,8 +75,8 @@
* Function prototypes -- internal to this file only
*/
static AbsoluteTime tm2abstime(struct tm * tm, int tz);
static void reltime2tm(RelativeTime time, struct tm * tm);
static AbsoluteTime tm2abstime(struct pg_tm * tm, int tz);
static void reltime2tm(RelativeTime time, struct pg_tm * tm);
static int istinterval(char *i_string,
AbsoluteTime *i_start,
AbsoluteTime *i_end);
@ -142,10 +141,10 @@ AbsoluteTimeUsecToTimestampTz(AbsoluteTime sec, int usec)
/*
* GetCurrentDateTime()
*
* Get the transaction start time ("now()") broken down as a struct tm.
* Get the transaction start time ("now()") broken down as a struct pg_tm.
*/
void
GetCurrentDateTime(struct tm * tm)
GetCurrentDateTime(struct pg_tm * tm)
{
int tz;
@ -155,11 +154,11 @@ GetCurrentDateTime(struct tm * tm)
/*
* GetCurrentTimeUsec()
*
* Get the transaction start time ("now()") broken down as a struct tm,
* Get the transaction start time ("now()") broken down as a struct pg_tm,
* including fractional seconds and timezone offset.
*/
void
GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp)
GetCurrentTimeUsec(struct pg_tm * tm, fsec_t *fsec, int *tzp)
{
int tz;
int usec;
@ -177,10 +176,10 @@ GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp)
void
abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
abstime2tm(AbsoluteTime _time, int *tzp, struct pg_tm * tm, char **tzn)
{
time_t time = (time_t) _time;
struct tm *tx;
struct pg_tm *tx;
/*
* If HasCTZSet is true then we have a brute force time zone
@ -191,9 +190,9 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
time -= CTimeZone;
if ((!HasCTZSet) && (tzp != NULL))
tx = localtime(&time);
tx = pg_localtime(&time);
else
tx = gmtime(&time);
tx = pg_gmtime(&time);
tm->tm_year = tx->tm_year + 1900;
tm->tm_mon = tx->tm_mon + 1;
@ -203,7 +202,6 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
tm->tm_sec = tx->tm_sec;
tm->tm_isdst = tx->tm_isdst;
#if defined(HAVE_TM_ZONE)
tm->tm_gmtoff = tx->tm_gmtoff;
tm->tm_zone = tx->tm_zone;
@ -248,66 +246,6 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
}
else
tm->tm_isdst = -1;
#elif defined(HAVE_INT_TIMEZONE)
if (tzp != NULL)
{
/*
* We have a brute force time zone per SQL99? Then use it without
* change since we have already rotated to the time zone.
*/
if (HasCTZSet)
{
*tzp = CTimeZone;
tm->tm_isdst = 0;
if (tzn != NULL)
*tzn = NULL;
}
else
{
*tzp = ((tm->tm_isdst > 0) ? (TIMEZONE_GLOBAL - 3600) : TIMEZONE_GLOBAL);
if (tzn != NULL)
{
/*
* Copy no more than MAXTZLEN bytes of timezone to tzn, in
* case it contains an error message, which doesn't fit in
* the buffer
*/
StrNCpy(*tzn, tzname[tm->tm_isdst], MAXTZLEN + 1);
if (strlen(tzname[tm->tm_isdst]) > MAXTZLEN)
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid time zone name: \"%s\"",
tzname[tm->tm_isdst])));
}
}
}
else
tm->tm_isdst = -1;
#else /* not (HAVE_TM_ZONE || HAVE_INT_TIMEZONE) */
if (tzp != NULL)
{
/*
* We have a brute force time zone per SQL99? Then use it without
* change since we have already rotated to the time zone.
*/
if (HasCTZSet)
{
*tzp = CTimeZone;
if (tzn != NULL)
*tzn = NULL;
}
else
{
/* default to UTC */
*tzp = 0;
if (tzn != NULL)
*tzn = NULL;
}
}
else
tm->tm_isdst = -1;
#endif
}
@ -316,7 +254,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
* Note that tm has full year (not 1900-based) and 1-based month.
*/
static AbsoluteTime
tm2abstime(struct tm * tm, int tz)
tm2abstime(struct pg_tm * tm, int tz)
{
int day;
AbsoluteTime sec;
@ -362,7 +300,7 @@ abstimein(PG_FUNCTION_ARGS)
AbsoluteTime result;
fsec_t fsec;
int tz = 0;
struct tm date,
struct pg_tm date,
*tm = &date;
int dterr;
char *field[MAXDATEFIELDS];
@ -428,7 +366,7 @@ abstimeout(PG_FUNCTION_ARGS)
char *result;
int tz;
double fsec = 0;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
char buf[MAXDATELEN + 1];
char zone[MAXDATELEN + 1],
@ -611,7 +549,7 @@ timestamp_abstime(PG_FUNCTION_ARGS)
AbsoluteTime result;
fsec_t fsec;
int tz;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
if (TIMESTAMP_IS_NOBEGIN(timestamp))
@ -642,7 +580,7 @@ abstime_timestamp(PG_FUNCTION_ARGS)
{
AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
Timestamp result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int tz;
char zone[MAXDATELEN + 1],
@ -687,7 +625,7 @@ timestamptz_abstime(PG_FUNCTION_ARGS)
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
AbsoluteTime result;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
if (TIMESTAMP_IS_NOBEGIN(timestamp))
@ -715,7 +653,7 @@ abstime_timestamptz(PG_FUNCTION_ARGS)
{
AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
TimestampTz result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int tz;
char zone[MAXDATELEN + 1],
@ -763,7 +701,7 @@ reltimein(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
RelativeTime result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
int dtype;
@ -811,7 +749,7 @@ reltimeout(PG_FUNCTION_ARGS)
{
RelativeTime time = PG_GETARG_RELATIVETIME(0);
char *result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
char buf[MAXDATELEN + 1];
@ -849,7 +787,7 @@ reltimesend(PG_FUNCTION_ARGS)
static void
reltime2tm(RelativeTime time, struct tm * tm)
reltime2tm(RelativeTime time, struct pg_tm * tm)
{
double dtime = time;
@ -1732,8 +1670,8 @@ timeofday(PG_FUNCTION_ARGS)
gettimeofday(&tp, &tpz);
tt = (time_t) tp.tv_sec;
strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
localtime(&tt));
pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
pg_localtime(&tt));
snprintf(buf, sizeof(buf), templ, tp.tv_usec);
len = VARHDRSZ + strlen(buf);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.105 2004/05/07 00:24:58 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.106 2004/05/21 05:08:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -70,7 +70,7 @@ timestamp_in(PG_FUNCTION_ARGS)
int32 typmod = PG_GETARG_INT32(2);
Timestamp result;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int tz;
int dtype;
@ -137,7 +137,7 @@ timestamp_out(PG_FUNCTION_ARGS)
{
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
char *result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
char *tzn = NULL;
@ -296,7 +296,7 @@ timestamptz_in(PG_FUNCTION_ARGS)
int32 typmod = PG_GETARG_INT32(2);
TimestampTz result;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int tz;
int dtype;
@ -364,7 +364,7 @@ timestamptz_out(PG_FUNCTION_ARGS)
TimestampTz dt = PG_GETARG_TIMESTAMPTZ(0);
char *result;
int tz;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
char *tzn;
@ -456,7 +456,7 @@ interval_in(PG_FUNCTION_ARGS)
int32 typmod = PG_GETARG_INT32(2);
Interval *result;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
int dtype;
int nf;
@ -520,7 +520,7 @@ interval_out(PG_FUNCTION_ARGS)
{
Interval *span = PG_GETARG_INTERVAL_P(0);
char *result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
char buf[MAXDATELEN + 1];
@ -933,23 +933,19 @@ dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
* local time zone. If out of this range, leave as GMT. - tgl 97/05/27
*/
int
timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
timestamp2tm(Timestamp dt, int *tzp, struct pg_tm * tm, fsec_t *fsec, char **tzn)
{
#ifdef HAVE_INT64_TIMESTAMP
int date,
date0;
int64 time;
#else
double date,
date0;
double time;
#endif
time_t utime;
#if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
struct tm *tx;
#endif
struct pg_tm *tx;
date0 = POSTGRES_EPOCH_JDATE;
@ -1006,10 +1002,8 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
{
*tzp = CTimeZone;
tm->tm_isdst = 0;
#if defined(HAVE_TM_ZONE)
tm->tm_gmtoff = CTimeZone;
tm->tm_zone = NULL;
#endif
if (tzn != NULL)
*tzn = NULL;
}
@ -1027,46 +1021,20 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
utime = (dt + ((date0 - UNIX_EPOCH_JDATE) * 86400));
#endif
#if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
tx = localtime(&utime);
tx = pg_localtime(&utime);
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;
#if NOT_USED
/* XXX HACK
* Argh! My Linux box puts in a 1 second offset for dates less than 1970
* but only if the seconds field was non-zero. So, don't copy the seconds
* field and instead carry forward from the original - thomas 97/06/18
* Note that Linux uses the standard freeware zic package as do
* many other platforms so this may not be Linux/ix86-specific.
* Still shows a problem on my up to date Linux box - thomas 2001-01-17
*/
tm->tm_sec = tx->tm_sec;
#endif
tm->tm_isdst = tx->tm_isdst;
#if defined(HAVE_TM_ZONE)
tm->tm_gmtoff = tx->tm_gmtoff;
tm->tm_zone = tx->tm_zone;
*tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
*tzp = -(tm->tm_gmtoff);
if (tzn != NULL)
*tzn = (char *) tm->tm_zone;
#elif defined(HAVE_INT_TIMEZONE)
*tzp = ((tm->tm_isdst > 0) ? (TIMEZONE_GLOBAL - 3600) : TIMEZONE_GLOBAL);
if (tzn != NULL)
*tzn = tzname[(tm->tm_isdst > 0)];
#endif
#else /* not (HAVE_TM_ZONE || HAVE_INT_TIMEZONE) */
*tzp = 0;
/* Mark this as *no* time zone available */
tm->tm_isdst = -1;
if (tzn != NULL)
*tzn = NULL;
#endif
}
else
{
@ -1096,12 +1064,11 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
* Returns -1 on failure (value out of range).
*/
int
tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
tm2timestamp(struct pg_tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
{
#ifdef HAVE_INT64_TIMESTAMP
int date;
int64 time;
#else
double date,
time;
@ -1135,11 +1102,10 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
* Convert a interval data type to a tm structure.
*/
int
interval2tm(Interval span, struct tm * tm, fsec_t *fsec)
interval2tm(Interval span, struct pg_tm * tm, fsec_t *fsec)
{
#ifdef HAVE_INT64_TIMESTAMP
int64 time;
#else
double time;
#endif
@ -1179,7 +1145,7 @@ interval2tm(Interval span, struct tm * tm, fsec_t *fsec)
}
int
tm2interval(struct tm * tm, fsec_t fsec, Interval *span)
tm2interval(struct pg_tm * tm, fsec_t fsec, Interval *span)
{
span->month = ((tm->tm_year * 12) + tm->tm_mon);
#ifdef HAVE_INT64_TIMESTAMP
@ -1251,12 +1217,12 @@ interval_finite(PG_FUNCTION_ARGS)
*---------------------------------------------------------*/
void
GetEpochTime(struct tm * tm)
GetEpochTime(struct pg_tm * tm)
{
struct tm *t0;
struct pg_tm *t0;
time_t epoch = 0;
t0 = gmtime(&epoch);
t0 = pg_gmtime(&epoch);
tm->tm_year = t0->tm_year;
tm->tm_mon = t0->tm_mon;
@ -1276,7 +1242,7 @@ Timestamp
SetEpochTimestamp(void)
{
Timestamp dt;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
GetEpochTime(tm);
@ -1896,7 +1862,7 @@ timestamp_pl_interval(PG_FUNCTION_ARGS)
{
if (span->month != 0)
{
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
@ -1974,7 +1940,7 @@ timestamptz_pl_interval(PG_FUNCTION_ARGS)
{
if (span->month != 0)
{
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
@ -2296,11 +2262,11 @@ timestamp_age(PG_FUNCTION_ARGS)
fsec_t fsec,
fsec1,
fsec2;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
struct tm tt1,
struct pg_tm tt1,
*tm1 = &tt1;
struct tm tt2,
struct pg_tm tt2,
*tm2 = &tt2;
result = (Interval *) palloc(sizeof(Interval));
@ -2407,11 +2373,11 @@ timestamptz_age(PG_FUNCTION_ARGS)
fsec_t fsec,
fsec1,
fsec2;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
struct tm tt1,
struct pg_tm tt1,
*tm1 = &tt1;
struct tm tt2,
struct pg_tm tt2,
*tm2 = &tt2;
result = (Interval *) palloc(sizeof(Interval));
@ -2702,7 +2668,7 @@ timestamp_trunc(PG_FUNCTION_ARGS)
val;
char *lowunits;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
if (TIMESTAMP_NOT_FINITE(timestamp))
@ -2806,7 +2772,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
char *lowunits;
fsec_t fsec;
char *tzn;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
if (TIMESTAMP_NOT_FINITE(timestamp))
@ -2909,7 +2875,7 @@ interval_trunc(PG_FUNCTION_ARGS)
val;
char *lowunits;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
result = (Interval *) palloc(sizeof(Interval));
@ -3142,7 +3108,7 @@ timestamp_part(PG_FUNCTION_ARGS)
val;
char *lowunits;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
if (TIMESTAMP_NOT_FINITE(timestamp))
@ -3355,7 +3321,7 @@ timestamptz_part(PG_FUNCTION_ARGS)
double dummy;
fsec_t fsec;
char *tzn;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
if (TIMESTAMP_NOT_FINITE(timestamp))
@ -3544,7 +3510,7 @@ interval_part(PG_FUNCTION_ARGS)
val;
char *lowunits;
fsec_t fsec;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
lowunits = downcase_truncate_identifier(VARDATA(units),
@ -3755,7 +3721,7 @@ static TimestampTz
timestamp2timestamptz(Timestamp timestamp)
{
TimestampTz result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
int tz;
@ -3788,7 +3754,7 @@ timestamptz_timestamp(PG_FUNCTION_ARGS)
{
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
Timestamp result;
struct tm tt,
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
char *tzn;

View File

@ -37,18 +37,16 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.136 2004/05/07 00:24:58 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.137 2004/05/21 05:08:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <ctype.h>
#ifdef HAVE_SYSLOG
#include <syslog.h>
@ -58,6 +56,7 @@
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "pgtime.h"
#include "storage/ipc.h"
#include "tcop/tcopprot.h"
#include "utils/memutils.h"
@ -1217,8 +1216,8 @@ log_line_prefix(StringInfo buf)
time_t stamp_time = time(NULL);
char strfbuf[128];
strftime(strfbuf, sizeof(strfbuf), "%Y-%m-%d %H:%M:%S %Z",
localtime(&stamp_time));
pg_strftime(strfbuf, sizeof(strfbuf), "%Y-%m-%d %H:%M:%S %Z",
pg_localtime(&stamp_time));
appendStringInfoString(buf, strfbuf);
}
break;
@ -1228,8 +1227,8 @@ log_line_prefix(StringInfo buf)
time_t stamp_time = MyProcPort->session_start.tv_sec;
char strfbuf[128];
strftime(strfbuf, sizeof(strfbuf), "%Y-%m-%d %H:%M:%S %Z",
localtime(&stamp_time));
pg_strftime(strfbuf, sizeof(strfbuf), "%Y-%m-%d %H:%M:%S %Z",
pg_localtime(&stamp_time));
appendStringInfoString(buf, strfbuf);
}
break;

View File

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.205 2004/05/08 02:11:46 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.206 2004/05/21 05:08:03 tgl Exp $
*
*--------------------------------------------------------------------
*/
@ -2094,10 +2094,6 @@ InitializeGUCOptions(void)
if (env != NULL)
SetConfigOption("datestyle", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
env = getenv("TZ");
if (env != NULL)
SetConfigOption("timezone", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
env = getenv("PGCLIENTENCODING");
if (env != NULL)
SetConfigOption("client_encoding", env, PGC_POSTMASTER, PGC_S_ENV_VAR);

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/c.h,v 1.164 2004/05/07 00:24:58 tgl Exp $
* $PostgreSQL: pgsql/src/include/c.h,v 1.165 2004/05/21 05:08:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -309,18 +309,6 @@ typedef unsigned long int uint64;
#define HAVE_INT64_TIMESTAMP
#endif
/* Global variable holding time zone information. */
#if defined(USE_PGTZ) && !defined(FRONTEND)
#define TIMEZONE_GLOBAL pg_timezone
#else
#ifndef HAVE_UNDERSCORE_TIMEZONE
#define TIMEZONE_GLOBAL timezone
#else
#define TIMEZONE_GLOBAL _timezone
#define tzname _tzname /* should be in time.h? */
#endif
#endif
/* sig_atomic_t is required by ANSI C, but may be missing on old platforms */
#ifndef HAVE_SIG_ATOMIC_T
typedef int sig_atomic_t;

View File

@ -8,16 +8,15 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.13 2004/02/11 22:55:26 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.14 2004/05/21 05:08:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PG_CONTROL_H
#define PG_CONTROL_H
#include <time.h>
#include "access/xlogdefs.h"
#include "pgtime.h"
#include "utils/pg_crc.h"

View File

@ -7,16 +7,13 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.51 2004/02/15 21:01:39 tgl Exp $
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.52 2004/05/21 05:08:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef VACUUM_H
#define VACUUM_H
#include <time.h>
#include <sys/time.h>
#ifdef HAVE_GETRUSAGE
#include <sys/resource.h>
#else
@ -28,6 +25,7 @@
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "nodes/parsenodes.h"
#include "pgtime.h"
#include "utils/rel.h"

View File

@ -11,16 +11,15 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/libpq/libpq-be.h,v 1.44 2004/04/05 03:16:21 momjian Exp $
* $PostgreSQL: pgsql/src/include/libpq/libpq-be.h,v 1.45 2004/05/21 05:08:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef LIBPQ_BE_H
#define LIBPQ_BE_H
#ifndef _MSC_VER
#include <sys/time.h>
#endif
#ifdef USE_SSL
#include <openssl/ssl.h>
#include <openssl/err.h>

View File

@ -615,9 +615,6 @@
/* Define to 1 to build with PAM support. (--with-pam) */
#undef USE_PAM
/* Define to 1 to use our own timezone library */
#undef USE_PGTZ
/* Define to 1 to build with Rendezvous support. (--with-rendezvous) */
#undef USE_RENDEZVOUS

View File

@ -6,7 +6,7 @@
* for developers. If you edit any of these, be sure to do a *full*
* rebuild (and an initdb if noted).
*
* $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.12 2004/03/24 22:40:29 tgl Exp $
* $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.13 2004/05/21 05:08:03 tgl Exp $
*------------------------------------------------------------------------
*/
@ -152,14 +152,6 @@
#define HAVE_WORKING_LINK 1
#endif
/*
* Define this if your operating system has _timezone rather than timezone
*/
#if defined(__CYGWIN__) || defined(WIN32)
#define HAVE_INT_TIMEZONE /* has int _timezone */
#define HAVE_UNDERSCORE_TIMEZONE 1
#endif
/*
* This is the default directory in which AF_UNIX socket files are
* placed. Caution: changing this risks breaking your existing client

73
src/include/pgtime.h Normal file
View File

@ -0,0 +1,73 @@
/*-------------------------------------------------------------------------
*
* pgtime.h
* PostgreSQL internal timezone library
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/include/pgtime.h,v 1.1 2004/05/21 05:08:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef _PGTIME_H
#define _PGTIME_H
#ifdef FRONTEND
/* Don't mess with anything for the frontends */
#include <time.h>
#else
/*
* Redefine functions and defines we implement, so we cause an
* error if someone tries to use the "base functions"
*/
#ifndef NO_REDEFINE_TIMEFUNCS
#define localtime DONOTUSETHIS_localtime
#define gmtime DONOTUSETHIS_gmtime
#define asctime DONOTUSETHIS_asctime
#define ctime DONOTUSETHIS_ctime
#define tzset DONOTUSETHIS_tzset
#define mktime DONOTUSETHIS_mktime
#define tzname DONOTUSETHIS_tzname
#define daylight DONOTUSETHIS_daylight
#define strftime DONOTUSETHIS_strftime
#endif
/* Then pull in default declarations, particularly time_t */
#include <time.h>
/*
* Now define prototype for our own timezone implementation
* structs and functions.
*/
struct pg_tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
long int tm_gmtoff;
const char *tm_zone;
};
extern struct pg_tm *pg_localtime(const time_t *);
extern struct pg_tm *pg_gmtime(const time_t *);
extern time_t pg_mktime(struct pg_tm *);
extern bool pg_tzset(const char *tzname);
extern size_t pg_strftime(char *s, size_t max, const char *format,
const struct pg_tm *tm);
extern void pg_timezone_initialize(void);
extern bool tz_acceptable(void);
extern const char *select_default_timezone(void);
extern const char *pg_get_current_timezone(void);
#endif /* FRONTEND */
#endif /* _PGTIME_H */

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/port.h,v 1.35 2004/05/20 15:38:11 momjian Exp $
* $PostgreSQL: pgsql/src/include/port.h,v 1.36 2004/05/21 05:08:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -220,37 +220,3 @@ extern int pqGethostbyname(const char *name,
#define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f))
#define WTERMSIG(w) ((w) & 0x7f)
#endif
/*
* Internal timezone library
*/
#ifdef USE_PGTZ
#ifndef FRONTEND
#undef localtime
#undef gmtime
#undef asctime
#undef ctime
#undef difftime
#undef mktime
#undef tzset
#define localtime(timep) pg_localtime(timep)
#define gmtime(timep) pg_gmtime(timep)
#define asctime(timep) pg_asctime(timep)
#define ctime(timep) pg_ctime(timep)
#define difftime(t1,t2) pg_difftime(t1,t2)
#define mktime(tm) pg_mktime(tm)
#define tzset pg_tzset
extern struct tm *pg_localtime(const time_t *);
extern struct tm *pg_gmtime(const time_t *);
extern char *pg_asctime(const struct tm *);
extern char *pg_ctime(const time_t *);
extern double pg_difftime(const time_t, const time_t);
extern time_t pg_mktime(struct tm *);
extern void pg_tzset(void);
extern time_t pg_timezone;
#endif
#endif

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.47 2004/01/19 19:04:40 tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.48 2004/05/21 05:08:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -18,8 +18,8 @@
#include <limits.h>
#include <math.h>
#include <time.h>
#include "pgtime.h"
#include "utils/timestamp.h"
@ -289,8 +289,8 @@ extern int day_tab[2][13];
#define DTERR_TZDISP_OVERFLOW (-5)
extern void GetCurrentDateTime(struct tm * tm);
extern void GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp);
extern void GetCurrentDateTime(struct pg_tm * tm);
extern void GetCurrentTimeUsec(struct pg_tm * tm, fsec_t *fsec, int *tzp);
extern void j2date(int jd, int *year, int *month, int *day);
extern int date2j(int year, int month, int day);
@ -299,30 +299,28 @@ extern int ParseDateTime(const char *timestr, char *lowstr,
int maxfields, int *numfields);
extern int DecodeDateTime(char **field, int *ftype,
int nf, int *dtype,
struct tm * tm, fsec_t *fsec, int *tzp);
struct pg_tm * tm, fsec_t *fsec, int *tzp);
extern int DecodeTimeOnly(char **field, int *ftype,
int nf, int *dtype,
struct tm * tm, fsec_t *fsec, int *tzp);
struct pg_tm * tm, fsec_t *fsec, int *tzp);
extern int DecodeInterval(char **field, int *ftype,
int nf, int *dtype,
struct tm * tm, fsec_t *fsec);
struct pg_tm * tm, fsec_t *fsec);
extern void DateTimeParseError(int dterr, const char *str,
const char *datatype);
extern int DetermineLocalTimeZone(struct tm * tm);
extern int DetermineLocalTimeZone(struct pg_tm * tm);
extern int EncodeDateOnly(struct tm * tm, int style, char *str);
extern int EncodeTimeOnly(struct tm * tm, fsec_t fsec, int *tzp, int style, char *str);
extern int EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str);
extern int EncodeInterval(struct tm * tm, fsec_t fsec, int style, char *str);
extern int EncodeDateOnly(struct pg_tm * tm, int style, char *str);
extern int EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, int *tzp, int style, char *str);
extern int EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str);
extern int EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str);
extern int DecodeSpecial(int field, char *lowtoken, int *val);
extern int DecodeUnits(int field, char *lowtoken, int *val);
extern int j2day(int jd);
extern int DecodePosixTimezone(char *str, int *tzp);
extern bool CheckDateTokenTables(void);
#endif /* DATETIME_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/nabstime.h,v 1.41 2003/11/29 22:41:15 pgsql Exp $
* $PostgreSQL: pgsql/src/include/utils/nabstime.h,v 1.42 2004/05/21 05:08:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -15,9 +15,9 @@
#define NABSTIME_H
#include <limits.h>
#include <time.h>
#include "fmgr.h"
#include "pgtime.h"
#include "utils/timestamp.h"
#include "utils/datetime.h"
@ -164,6 +164,6 @@ extern Datum timeofday(PG_FUNCTION_ARGS);
extern AbsoluteTime GetCurrentAbsoluteTime(void);
extern AbsoluteTime GetCurrentAbsoluteTimeUsec(int *usec);
extern TimestampTz AbsoluteTimeUsecToTimestampTz(AbsoluteTime sec, int usec);
extern void abstime2tm(AbsoluteTime time, int *tzp, struct tm * tm, char **tzn);
extern void abstime2tm(AbsoluteTime time, int *tzp, struct pg_tm * tm, char **tzn);
#endif /* NABSTIME_H */

View File

@ -6,19 +6,19 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.36 2004/05/01 19:25:08 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.37 2004/05/21 05:08:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef TIMESTAMP_H
#define TIMESTAMP_H
#include <time.h>
#include <math.h>
#include <limits.h>
#include <float.h>
#include "fmgr.h"
#include "pgtime.h"
#ifdef HAVE_INT64_TIMESTAMP
#include "utils/int8.h"
#endif
@ -251,16 +251,16 @@ extern Datum now(PG_FUNCTION_ARGS);
/* Internal routines (not fmgr-callable) */
extern int tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *dt);
extern int timestamp2tm(Timestamp dt, int *tzp, struct tm * tm,
extern int tm2timestamp(struct pg_tm * tm, fsec_t fsec, int *tzp, Timestamp *dt);
extern int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm * tm,
fsec_t *fsec, char **tzn);
extern void dt2time(Timestamp dt, int *hour, int *min, int *sec, fsec_t *fsec);
extern int interval2tm(Interval span, struct tm * tm, fsec_t *fsec);
extern int tm2interval(struct tm * tm, fsec_t fsec, Interval *span);
extern int interval2tm(Interval span, struct pg_tm * tm, fsec_t *fsec);
extern int tm2interval(struct pg_tm * tm, fsec_t fsec, Interval *span);
extern Timestamp SetEpochTimestamp(void);
extern void GetEpochTime(struct tm * tm);
extern void GetEpochTime(struct pg_tm * tm);
extern int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2);
/* timestamp comparison works for timestamptz also */

View File

@ -1,5 +1,5 @@
/*
* $PostgreSQL: pgsql/src/port/gettimeofday.c,v 1.3 2003/11/29 19:52:13 pgsql Exp $
* $PostgreSQL: pgsql/src/port/gettimeofday.c,v 1.4 2004/05/21 05:08:05 tgl Exp $
*
* Copyright (c) 2003 SRA, Inc.
* Copyright (c) 2003 SKC, Inc.
@ -25,7 +25,8 @@
#include "postgres.h"
#include "sys/time.h"
#include <sys/time.h>
/* FILETIME of Jan 1 1970 00:00:00. */
static const unsigned __int64 epoch = 116444736000000000L;

View File

@ -1,130 +0,0 @@
--
-- ABSTIME
-- testing built-in time type abstime
-- uses reltime and tinterval
--
--
-- timezones may vary based not only on location but the operating
-- system. the main correctness issue is that the OS may not get
-- daylight savings time right for times prior to Unix epoch (jan 1 1970).
--
CREATE TABLE ABSTIME_TBL (f1 abstime);
BEGIN;
INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'now');
INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'now');
SELECT count(*) AS two FROM ABSTIME_TBL WHERE f1 = 'now' ;
two
-----
2
(1 row)
END;
DELETE FROM ABSTIME_TBL;
INSERT INTO ABSTIME_TBL (f1) VALUES ('Jan 14, 1973 03:14:21');
INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'Mon May 1 00:30:30 1995');
INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'epoch');
INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'infinity');
INSERT INTO ABSTIME_TBL (f1) VALUES (abstime '-infinity');
INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'May 10, 1947 23:59:12');
-- what happens if we specify slightly misformatted abstime?
INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 35, 1946 10:00:00');
ERROR: date/time field value out of range: "Feb 35, 1946 10:00:00"
HINT: Perhaps you need a different "datestyle" setting.
INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 28, 1984 25:08:10');
ERROR: date/time field value out of range: "Feb 28, 1984 25:08:10"
-- badly formatted abstimes: these should result in invalid abstimes
INSERT INTO ABSTIME_TBL (f1) VALUES ('bad date format');
ERROR: invalid input syntax for type abstime: "bad date format"
INSERT INTO ABSTIME_TBL (f1) VALUES ('Jun 10, 1843');
-- test abstime operators
SELECT '' AS eight, ABSTIME_TBL.*;
eight | f1
-------+------------------------------
| Sun Jan 14 03:14:21 1973 PST
| Mon May 01 00:30:30 1995 PDT
| Wed Dec 31 16:00:00 1969 PST
| infinity
| -infinity
| Sat May 10 23:59:12 1947 PDT
| invalid
(7 rows)
SELECT '' AS six, ABSTIME_TBL.*
WHERE ABSTIME_TBL.f1 < abstime 'Jun 30, 2001';
six | f1
-----+------------------------------
| Sun Jan 14 03:14:21 1973 PST
| Mon May 01 00:30:30 1995 PDT
| Wed Dec 31 16:00:00 1969 PST
| -infinity
| Sat May 10 23:59:12 1947 PDT
(5 rows)
SELECT '' AS six, ABSTIME_TBL.*
WHERE ABSTIME_TBL.f1 > abstime '-infinity';
six | f1
-----+------------------------------
| Sun Jan 14 03:14:21 1973 PST
| Mon May 01 00:30:30 1995 PDT
| Wed Dec 31 16:00:00 1969 PST
| infinity
| Sat May 10 23:59:12 1947 PDT
| invalid
(6 rows)
SELECT '' AS six, ABSTIME_TBL.*
WHERE abstime 'May 10, 1947 23:59:12' <> ABSTIME_TBL.f1;
six | f1
-----+------------------------------
| Sun Jan 14 03:14:21 1973 PST
| Mon May 01 00:30:30 1995 PDT
| Wed Dec 31 16:00:00 1969 PST
| infinity
| -infinity
| invalid
(6 rows)
SELECT '' AS three, ABSTIME_TBL.*
WHERE abstime 'epoch' >= ABSTIME_TBL.f1;
three | f1
-------+------------------------------
| Wed Dec 31 16:00:00 1969 PST
| -infinity
| Sat May 10 23:59:12 1947 PDT
(3 rows)
SELECT '' AS four, ABSTIME_TBL.*
WHERE ABSTIME_TBL.f1 <= abstime 'Jan 14, 1973 03:14:21';
four | f1
------+------------------------------
| Sun Jan 14 03:14:21 1973 PST
| Wed Dec 31 16:00:00 1969 PST
| -infinity
| Sat May 10 23:59:12 1947 PDT
(4 rows)
SELECT '' AS four, ABSTIME_TBL.*
WHERE ABSTIME_TBL.f1 <?>
tinterval '["Apr 1 1950 00:00:00" "Dec 30 1999 23:00:00"]';
four | f1
------+------------------------------
| Sun Jan 14 03:14:21 1973 PST
| Mon May 01 00:30:30 1995 PDT
| Wed Dec 31 16:00:00 1969 PST
(3 rows)
SELECT '' AS four, f1 AS abstime,
date_part('year', f1) AS year, date_part('month', f1) AS month,
date_part('day',f1) AS day, date_part('hour', f1) AS hour,
date_part('minute', f1) AS minute, date_part('second', f1) AS second
FROM ABSTIME_TBL
WHERE isfinite(f1)
ORDER BY abstime;
four | abstime | year | month | day | hour | minute | second
------+------------------------------+------+-------+-----+------+--------+--------
| Sat May 10 23:59:12 1947 PDT | 1947 | 5 | 10 | 23 | 59 | 12
| Wed Dec 31 16:00:00 1969 PST | 1969 | 12 | 31 | 16 | 0 | 0
| Sun Jan 14 03:14:21 1973 PST | 1973 | 1 | 14 | 3 | 14 | 21
| Mon May 01 00:30:30 1995 PDT | 1995 | 5 | 1 | 0 | 30 | 30
(4 rows)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,170 +0,0 @@
--
-- TINTERVAL
--
CREATE TABLE TINTERVAL_TBL (f1 tinterval);
-- Should accept any abstime,
-- so do not bother with extensive testing of values
INSERT INTO TINTERVAL_TBL (f1)
VALUES ('["-infinity" "infinity"]');
INSERT INTO TINTERVAL_TBL (f1)
VALUES ('["May 10, 1947 23:59:12" "Jan 14, 1973 03:14:21"]');
INSERT INTO TINTERVAL_TBL (f1)
VALUES ('["Sep 4, 1983 23:59:12" "Oct 4, 1983 23:59:12"]');
INSERT INTO TINTERVAL_TBL (f1)
VALUES ('["epoch" "Mon May 1 00:30:30 1995"]');
INSERT INTO TINTERVAL_TBL (f1)
VALUES ('["Feb 15 1990 12:15:03" "2001-09-23 11:12:13"]');
-- badly formatted tintervals
INSERT INTO TINTERVAL_TBL (f1)
VALUES ('["bad time specifications" ""]');
ERROR: invalid input syntax for type abstime: "bad time specifications"
INSERT INTO TINTERVAL_TBL (f1)
VALUES ('["" "infinity"]');
ERROR: invalid input syntax for type abstime: ""
-- test tinterval operators
SELECT '' AS five, TINTERVAL_TBL.*;
five | f1
------+-----------------------------------------------------------------
| ["-infinity" "infinity"]
| ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"]
| ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
| ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"]
(5 rows)
-- length ==
SELECT '' AS one, t.*
FROM TINTERVAL_TBL t
WHERE t.f1 #= '@ 1 months';
one | f1
-----+-----------------------------------------------------------------
| ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"]
(1 row)
-- length <>
SELECT '' AS three, t.*
FROM TINTERVAL_TBL t
WHERE t.f1 #<> '@ 1 months';
three | f1
-------+-----------------------------------------------------------------
| ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
| ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"]
(3 rows)
-- length <
SELECT '' AS zero, t.*
FROM TINTERVAL_TBL t
WHERE t.f1 #< '@ 1 month';
zero | f1
------+----
(0 rows)
-- length <=
SELECT '' AS one, t.*
FROM TINTERVAL_TBL t
WHERE t.f1 #<= '@ 1 month';
one | f1
-----+-----------------------------------------------------------------
| ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"]
(1 row)
-- length >
SELECT '' AS three, t.*
FROM TINTERVAL_TBL t
WHERE t.f1 #> '@ 1 year';
three | f1
-------+-----------------------------------------------------------------
| ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
| ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"]
(3 rows)
-- length >=
SELECT '' AS three, t.*
FROM TINTERVAL_TBL t
WHERE t.f1 #>= '@ 3 years';
three | f1
-------+-----------------------------------------------------------------
| ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
| ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"]
(3 rows)
-- overlaps
SELECT '' AS three, t1.*
FROM TINTERVAL_TBL t1
WHERE t1.f1 &&
tinterval '["Aug 15 14:23:19 1983" "Sep 16 14:23:19 1983"]';
three | f1
-------+-----------------------------------------------------------------
| ["-infinity" "infinity"]
| ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
(3 rows)
SET geqo TO 'off';
SELECT '' AS five, t1.f1, t2.f1
FROM TINTERVAL_TBL t1, TINTERVAL_TBL t2
WHERE t1.f1 && t2.f1 and
t1.f1 = t2.f1
ORDER BY t1.f1, t2.f1;
five | f1 | f1
------+-----------------------------------------------------------------+-----------------------------------------------------------------
| ["-infinity" "infinity"] | ["-infinity" "infinity"]
| ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"]
| ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
| ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"] | ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"]
(5 rows)
SELECT '' AS fourteen, t1.f1 AS interval1, t2.f1 AS interval2
FROM TINTERVAL_TBL t1, TINTERVAL_TBL t2
WHERE t1.f1 && t2.f1 and not t1.f1 = t2.f1
ORDER BY interval1, interval2;
fourteen | interval1 | interval2
----------+-----------------------------------------------------------------+-----------------------------------------------------------------
| ["-infinity" "infinity"] | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"]
| ["-infinity" "infinity"] | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"]
| ["-infinity" "infinity"] | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
| ["-infinity" "infinity"] | ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"]
| ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] | ["-infinity" "infinity"]
| ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
| ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] | ["-infinity" "infinity"]
| ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] | ["-infinity" "infinity"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] | ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"]
| ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"] | ["-infinity" "infinity"]
| ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"] | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
(14 rows)
-- contains
SELECT '' AS five, t1.f1
FROM TINTERVAL_TBL t1
WHERE not t1.f1 <<
tinterval '["Aug 15 14:23:19 1980" "Sep 16 14:23:19 1990"]'
ORDER BY t1.f1;
five | f1
------+-----------------------------------------------------------------
| ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"]
| ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"]
| ["Sat May 10 23:59:12 1947 PDT" "Sun Jan 14 03:14:21 1973 PST"]
(3 rows)
-- make time interval
SELECT '' AS three, t1.f1
FROM TINTERVAL_TBL t1
WHERE t1.f1 &&
(abstime 'Aug 15 14:23:19 1983' <#>
abstime 'Sep 16 14:23:19 1983')
ORDER BY t1.f1;
three | f1
-------+-----------------------------------------------------------------
| ["-infinity" "infinity"]
| ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"]
| ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"]
(3 rows)
RESET geqo;

View File

@ -1,11 +1,3 @@
abstime/.*-aix4=abstime-solaris-1947
abstime/.*-aix5=abstime-solaris-1947
abstime/alpha.*-dec-osf=abstime-solaris-1947
abstime/.*-irix=abstime-solaris-1947
abstime/i.86-pc-solaris=abstime-solaris-1947
abstime/sparc-sun-solaris=abstime-solaris-1947
abstime/.*-sco=abstime-solaris-1947
abstime/.*-sysv5=abstime-solaris-1947
float4/.*-qnx=float4-exp-three-digits
float4/i.86-pc-mingw32=float4-exp-three-digits
float8/i.86-.*-freebsd[234]=float8-small-is-zero
@ -14,24 +6,5 @@ float8/i.86-.*-netbsd=float8-small-is-zero
float8/.*-qnx=float8-exp-three-digits
float8/i.86-pc-mingw32=float8-exp-three-digits-win32
float8/i.86-pc-cygwin=float8-small-is-zero
horology/.*-aix4=horology-solaris-1947
horology/.*-aix5=horology-solaris-1947
horology/alpha.*-dec-osf=horology-solaris-1947
horology/.*-cygwin=horology-no-DST-before-1970
horology/.*-hpux=horology-no-DST-before-1970
horology/.*-irix=horology-solaris-1947
horology/i.86-pc-solaris=horology-solaris-1947
horology/sparc-sun-solaris=horology-solaris-1947
horology/sparc-sun-sunos4.*=horology-no-DST-before-1970
horology/.*-sysv5=horology-solaris-1947
horology/.*-sco=horology-solaris-1947
int8/.*-qnx=int8-exp-three-digits
int8/i.86-pc-mingw32=int8-exp-three-digits-win32
tinterval/.*-aix4=tinterval-solaris-1947
tinterval/.*-aix5=tinterval-solaris-1947
tinterval/alpha.*-dec-osf=tinterval-solaris-1947
tinterval/.*-irix=tinterval-solaris-1947
tinterval/i.86-pc-solaris=tinterval-solaris-1947
tinterval/sparc-sun-solaris=tinterval-solaris-1947
tinterval/.*-sysv5=tinterval-solaris-1947
tinterval/.*-sco=tinterval-solaris-1947

View File

@ -4,7 +4,7 @@
# Makefile for the timezone library
# IDENTIFICATION
# $PostgreSQL: pgsql/src/timezone/Makefile,v 1.9 2004/05/18 04:10:33 momjian Exp $
# $PostgreSQL: pgsql/src/timezone/Makefile,v 1.10 2004/05/21 05:08:06 tgl Exp $
#
#-------------------------------------------------------------------------
@ -12,13 +12,17 @@ subdir = src/timezone
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
OBJS= asctime.o difftime.o localtime.o pgtz.o
ZICOBJS= zic.o ialloc.o scheck.o localtime.o asctime.o pgtz.o
# files to build into backend
OBJS= localtime.o strftime.o pgtz.o
TZDATA := africa antarctica asia australasia europe northamerica southamerica pacificnew etcetera factory backward systemv solar87 solar88 solar89
# files needed to build zic utility program
ZICOBJS= zic.o ialloc.o scheck.o localtime.o
# timezone data files
TZDATA := africa antarctica asia australasia europe northamerica southamerica \
pacificnew etcetera factory backward systemv solar87 solar88 solar89
TZDATAFILES := $(TZDATA:%=data/%)
ifeq ($(USE_PGTZ), yes)
all: SUBSYS.o submake-libpgport zic
SUBSYS.o: $(OBJS)
@ -31,6 +35,4 @@ install: all installdirs
./zic -d $(DESTDIR)$(datadir)/timezone $(TZDATAFILES)
clean distclean maintainer-clean:
rm -f SUBSYS.o $(OBJS) $(ZICOBJS)
endif
rm -f SUBSYS.o zic $(OBJS) $(ZICOBJS)

View File

@ -3,15 +3,3 @@ from:
ftp://elsie.nci.nih.gov/pub/tz*.tar.gz
The interface is used when USE_PGTZ is defined at the top level. This
will cause the following functions to be redefined:
localtime pg_localtime
gmtime pg_gmtime
asctime pg_asctime
ctime pg_ctime
difftime pg_difftime
mktime pg_mktime
tzset pg_tzset
and the TIMEZONE_GLOBAL define in c.h is redefined to pg_timezone.

View File

@ -1,75 +0,0 @@
#include "pgtz.h"
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
*/
#ifndef lint
#ifndef NOID
static char elsieid[] = "@(#)asctime.c 7.9";
#endif /* !defined NOID */
#endif /* !defined lint */
/*LINTLIBRARY*/
#include "private.h"
#include "tzfile.h"
/*
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, Second Edition, 1996-07-12.
*/
char *
asctime_r(timeptr, buf)
register const struct tm * timeptr;
char * buf;
{
static const char wday_name[][3] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char mon_name[][3] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
register const char * wn;
register const char * mn;
if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
wn = "???";
else wn = wday_name[timeptr->tm_wday];
if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
mn = "???";
else mn = mon_name[timeptr->tm_mon];
/*
** The X3J11-suggested format is
** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n"
** Since the .2 in 02.2d is ignored, we drop it.
*/
(void) sprintf(buf, "%.3s %.3s%3d %02d:%02d:%02d %d\n",
wn, mn,
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec,
TM_YEAR_BASE + timeptr->tm_year);
return buf;
}
/*
** A la X3J11, with core dump avoidance.
*/
char *
asctime(timeptr)
register const struct tm * timeptr;
{
/*
** Big enough for something such as
** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
** (two three-character abbreviations, five strings denoting integers,
** three explicit spaces, two explicit colons, a newline,
** and a trailing ASCII nul).
*/
static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) +
3 + 2 + 1 + 1];
return asctime_r(timeptr, result);
}

View File

@ -1,84 +0,0 @@
#include "pgtz.h"
/*
** This file is in the public domain, so clarified as of
** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
*/
#ifndef lint
#ifndef NOID
static char elsieid[] = "@(#)difftime.c 7.9";
#endif /* !defined NOID */
#endif /* !defined lint */
/*LINTLIBRARY*/
#include "private.h"
/*
** Algorithm courtesy Paul Eggert (eggert@twinsun.com).
*/
#ifdef HAVE_LONG_DOUBLE
#define long_double long double
#endif /* defined HAVE_LONG_DOUBLE */
#ifndef HAVE_LONG_DOUBLE
#define long_double double
#endif /* !defined HAVE_LONG_DOUBLE */
double
difftime(time1, time0)
const time_t time1;
const time_t time0;
{
time_t delta;
time_t hibit;
{
time_t tt;
double d;
long_double ld;
if (sizeof tt < sizeof d)
return (double) time1 - (double) time0;
if (sizeof tt < sizeof ld)
return (long_double) time1 - (long_double) time0;
}
if (time1 < time0)
return -difftime(time0, time1);
/*
** As much as possible, avoid loss of precision
** by computing the difference before converting to double.
*/
delta = time1 - time0;
if (delta >= 0)
return delta;
/*
** Repair delta overflow.
*/
hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1);
/*
** The following expression rounds twice, which means
** the result may not be the closest to the true answer.
** For example, suppose time_t is 64-bit signed int,
** long_double is IEEE 754 double with default rounding,
** time1 = 9223372036854775807 and time0 = -1536.
** Then the true difference is 9223372036854777343,
** which rounds to 9223372036854777856
** with a total error of 513.
** But delta overflows to -9223372036854774273,
** which rounds to -9223372036854774784, and correcting
** this by subtracting 2 * (long_double) hibit
** (i.e. by adding 2**64 = 18446744073709551616)
** yields 9223372036854776832, which
** rounds to 9223372036854775808
** with a total error of 1535 instead.
** This problem occurs only with very large differences.
** It's too painful to fix this portably.
** We are not alone in this problem;
** some C compilers round twice when converting
** large unsigned types to small floating types,
** so if time_t is unsigned the "return delta" above
** has the same double-rounding problem with those compilers.
*/
return delta - 2 * (long_double) hibit;
}

View File

@ -1,46 +1,30 @@
#ifndef lint
#ifndef NOID
static char elsieid[] = "@(#)ialloc.c 8.29";
#endif /* !defined NOID */
#endif /* !defined lint */
/*LINTLIBRARY*/
#include "postgres.h"
#include "private.h"
#define nonzero(n) (((n) == 0) ? 1 : (n))
char *
imalloc(n)
const int n;
char *imalloc(const int n)
{
return malloc((size_t) nonzero(n));
}
char *
icalloc(nelem, elsize)
int nelem;
int elsize;
char *icalloc(int nelem, int elsize)
{
if (nelem == 0 || elsize == 0)
nelem = elsize = 1;
return calloc((size_t) nelem, (size_t) elsize);
}
void *
irealloc(pointer, size)
void * const pointer;
const int size;
void *irealloc(void *pointer, const int size)
{
if (pointer == NULL)
return imalloc(size);
return realloc((void *) pointer, (size_t) nonzero(size));
}
char *
icatalloc(old, new)
char * const old;
const char * const new;
char *icatalloc(char *old, const char *new)
{
register char * result;
register int oldsize, newsize;
@ -57,24 +41,18 @@ const char * const new;
return result;
}
char *
icpyalloc(string)
const char * const string;
char *icpyalloc(const char *string)
{
return icatalloc((char *) NULL, string);
}
void
ifree(p)
char * const p;
void ifree(char *p)
{
if (p != NULL)
(void) free(p);
}
void
icfree(p)
char * const p;
void icfree(char *p)
{
if (p != NULL)
(void) free(p);

View File

@ -1,41 +1,22 @@
#include "pgtz.h"
#undef open
#define timezone pg_timezone
#define USG_COMPAT
extern time_t pg_timezone;
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
*/
#ifndef lint
#ifndef NOID
static char elsieid[] = "@(#)localtime.c 7.78";
#endif /* !defined NOID */
#endif /* !defined lint */
/*
** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu).
** POSIX-style TZ environment variable handling from Guy Harris
** (guy@auspex.com).
*/
/*LINTLIBRARY*/
#include "postgres.h"
#include <fcntl.h>
#include "pgtz.h"
#include "private.h"
#include "tzfile.h"
#include "fcntl.h"
/*
** SunOS 4.1.1 headers lack O_BINARY.
*/
#ifdef O_BINARY
#define OPEN_MODE (O_RDONLY | O_BINARY)
#endif /* defined O_BINARY */
#ifndef O_BINARY
#define OPEN_MODE O_RDONLY
#endif /* !defined O_BINARY */
#ifndef WILDABBR
/*
@ -71,9 +52,7 @@ static const char gmt[] = "GMT";
** implementation dependent; for historical reasons, US rules are a
** common default.
*/
#ifndef TZDEFRULESTRING
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
#endif /* !defined TZDEFDST */
struct ttinfo { /* time type information */
long tt_gmtoff; /* UTC offset in seconds */
@ -90,13 +69,6 @@ struct lsinfo { /* leap second information */
#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
#ifdef TZNAME_MAX
#define MY_TZNAME_MAX TZNAME_MAX
#endif /* defined TZNAME_MAX */
#ifndef TZNAME_MAX
#define MY_TZNAME_MAX 255
#endif /* !defined TZNAME_MAX */
struct state {
int leapcnt;
int timecnt;
@ -106,7 +78,7 @@ struct state {
unsigned char types[TZ_MAX_TIMES];
struct ttinfo ttis[TZ_MAX_TYPES];
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
(2 * (MY_TZNAME_MAX + 1)))];
(2 * (TZ_STRLEN_MAX + 1)))];
struct lsinfo lsis[TZ_MAX_LEAPS];
};
@ -126,68 +98,34 @@ struct rule {
** Prototypes for static functions.
*/
static long detzcode P((const char * codep));
static const char * getzname P((const char * strp));
static const char * getnum P((const char * strp, int * nump, int min,
int max));
static const char * getsecs P((const char * strp, long * secsp));
static const char * getoffset P((const char * strp, long * offsetp));
static const char * getrule P((const char * strp, struct rule * rulep));
static void gmtload P((struct state * sp));
static void gmtsub P((const time_t * timep, long offset,
struct tm * tmp));
static void localsub P((const time_t * timep, long offset,
struct tm * tmp));
static int increment_overflow P((int * number, int delta));
static int normalize_overflow P((int * tensptr, int * unitsptr,
int base));
static void settzname P((void));
static time_t time1 P((struct tm * tmp,
void(*funcp) P((const time_t *,
long, struct tm *)),
long offset));
static time_t time2 P((struct tm *tmp,
void(*funcp) P((const time_t *,
long, struct tm*)),
long offset, int * okayp));
static time_t time2sub P((struct tm *tmp,
void(*funcp) P((const time_t *,
long, struct tm*)),
long offset, int * okayp, int do_norm_secs));
static void timesub P((const time_t * timep, long offset,
const struct state * sp, struct tm * tmp));
static int tmcomp P((const struct tm * atmp,
const struct tm * btmp));
static time_t transtime P((time_t janfirst, int year,
const struct rule * rulep, long offset));
static int tzload P((const char * name, struct state * sp));
static int tzparse P((const char * name, struct state * sp,
int lastditch));
static long detzcode(const char *codep);
static const char *getzname(const char *strp);
static const char *getnum(const char *strp, int *nump, int min, int max);
static const char *getsecs(const char *strp, long *secsp);
static const char *getoffset(const char *strp, long *offsetp);
static const char *getrule(const char *strp, struct rule *rulep);
static void gmtload(struct state *sp);
static void gmtsub(const time_t *timep, long offset, struct pg_tm *tmp);
static void localsub(const time_t *timep, long offset, struct pg_tm *tmp);
static int increment_overflow(int *number, int delta);
static int normalize_overflow(int *tensptr, int *unitsptr, int base);
static time_t time1(struct pg_tm *tmp, void(*funcp)(const time_t *, long, struct pg_tm *), long offset);
static time_t time2(struct pg_tm *tmp, void(*funcp)(const time_t *, long, struct pg_tm *), long offset, int *okayp);
static time_t time2sub(struct pg_tm *tmp, void(*funcp)(const time_t *, long, struct pg_tm *), long offset, int *okayp, int do_norm_secs);
static void timesub(const time_t *timep, long offset, const struct state *sp, struct pg_tm *tmp);
static int tmcomp(const struct pg_tm *atmp, const struct pg_tm *btmp);
static time_t transtime(time_t janfirst, int year, const struct rule *rulep, long offset);
static int tzload(const char *name, struct state *sp);
static int tzparse(const char *name, struct state *sp, int lastditch);
#ifdef ALL_STATE
static struct state * lclptr;
static struct state * gmtptr;
#endif /* defined ALL_STATE */
#ifndef ALL_STATE
static struct state lclmem;
static struct state gmtmem;
#define lclptr (&lclmem)
#define gmtptr (&gmtmem)
#endif /* State Farm */
#ifndef TZ_STRLEN_MAX
#define TZ_STRLEN_MAX 255
#endif /* !defined TZ_STRLEN_MAX */
static char lcl_TZname[TZ_STRLEN_MAX + 1];
static int lcl_is_set;
static int gmt_is_set;
char * tzname[2] = {
wildabbr,
wildabbr
};
static int lcl_is_set=0;
static int gmt_is_set=0;
/*
** Section 4.12.3 of X3.159-1989 requires that
@ -197,20 +135,10 @@ char * tzname[2] = {
** Thanks to Paul Eggert (eggert@twinsun.com) for noting this.
*/
static struct tm tm;
static struct pg_tm tm;
#ifdef USG_COMPAT
time_t timezone = 0;
int daylight = 0;
#endif /* defined USG_COMPAT */
#ifdef ALTZONE
time_t altzone = 0;
#endif /* defined ALTZONE */
static long
detzcode(codep)
const char * const codep;
static long detzcode(const char *codep)
{
register long result;
register int i;
@ -221,60 +149,7 @@ const char * const codep;
return result;
}
static void
settzname P((void))
{
register struct state * const sp = lclptr;
register int i;
tzname[0] = wildabbr;
tzname[1] = wildabbr;
#ifdef USG_COMPAT
daylight = 0;
timezone = 0;
#endif /* defined USG_COMPAT */
#ifdef ALTZONE
altzone = 0;
#endif /* defined ALTZONE */
#ifdef ALL_STATE
if (sp == NULL) {
tzname[0] = tzname[1] = gmt;
return;
}
#endif /* defined ALL_STATE */
for (i = 0; i < sp->typecnt; ++i) {
register const struct ttinfo * const ttisp = &sp->ttis[i];
tzname[ttisp->tt_isdst] =
&sp->chars[ttisp->tt_abbrind];
#ifdef USG_COMPAT
if (ttisp->tt_isdst)
daylight = 1;
if (i == 0 || !ttisp->tt_isdst)
timezone = -(ttisp->tt_gmtoff);
#endif /* defined USG_COMPAT */
#ifdef ALTZONE
if (i == 0 || ttisp->tt_isdst)
altzone = -(ttisp->tt_gmtoff);
#endif /* defined ALTZONE */
}
/*
** And to get the latest zone names into tzname. . .
*/
for (i = 0; i < sp->timecnt; ++i) {
register const struct ttinfo * const ttisp =
&sp->ttis[
sp->types[i]];
tzname[ttisp->tt_isdst] =
&sp->chars[ttisp->tt_abbrind];
}
}
static int
tzload(name, sp)
register const char * name;
register struct state * const sp;
static int tzload(register const char *name, register struct state *sp)
{
register const char * p;
register int i;
@ -284,20 +159,14 @@ register struct state * const sp;
return -1;
{
register int doaccess;
/*
** Section 4.9.1 of the C standard says that
** "FILENAME_MAX expands to an integral constant expression
** that is the size needed for an array of char large enough
** to hold the longest file name string that the implementation
** guarantees can be opened."
*/
char fullname[FILENAME_MAX + 1];
char fullname[MAXPGPATH];
if (name[0] == ':')
++name;
doaccess = name[0] == '/';
if (!doaccess) {
if ((p = TZDIR) == NULL)
p = pg_TZDIR();
if (p == NULL)
return -1;
if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
return -1;
@ -313,7 +182,7 @@ register struct state * const sp;
}
if (doaccess && access(name, R_OK) != 0)
return -1;
if ((fid = open(name, OPEN_MODE)) == -1)
if ((fid = open(name, O_RDONLY | PG_BINARY)) == -1)
return -1;
}
{
@ -430,9 +299,7 @@ static const int year_lengths[2] = {
** character.
*/
static const char *
getzname(strp)
register const char * strp;
static const char *getzname(register const char *strp)
{
register char c;
@ -449,12 +316,7 @@ register const char * strp;
** Otherwise, return a pointer to the first character not part of the number.
*/
static const char *
getnum(strp, nump, min, max)
register const char * strp;
int * const nump;
const int min;
const int max;
static const char *getnum(register const char *strp, int *nump, const int min, const int max)
{
register char c;
register int num;
@ -482,10 +344,7 @@ const int max;
** of seconds.
*/
static const char *
getsecs(strp, secsp)
register const char * strp;
long * const secsp;
static const char *getsecs(register const char *strp, long *secsp)
{
int num;
@ -524,10 +383,7 @@ long * const secsp;
** Otherwise, return a pointer to the first character not part of the time.
*/
static const char *
getoffset(strp, offsetp)
register const char * strp;
long * const offsetp;
static const char *getoffset(register const char *strp, long *offsetp)
{
register int neg = 0;
@ -551,10 +407,7 @@ long * const offsetp;
** Otherwise, return a pointer to the first character not part of the rule.
*/
static const char *
getrule(strp, rulep)
const char * strp;
register struct rule * const rulep;
static const char *getrule(const char *strp, register struct rule *rulep)
{
if (*strp == 'J') {
/*
@ -605,19 +458,13 @@ register struct rule * const rulep;
** calculate the Epoch-relative time that rule takes effect.
*/
static time_t
transtime(janfirst, year, rulep, offset)
const time_t janfirst;
const int year;
register const struct rule * const rulep;
const long offset;
static time_t transtime(const time_t janfirst, const int year, register const struct rule *rulep, const long offset)
{
register int leapyear;
register time_t value;
register time_t value = 0;
register int i;
int d, m1, yy0, yy1, yy2, dow;
INITIALIZE(value);
leapyear = isleap(year);
switch (rulep->r_type) {
@ -700,14 +547,10 @@ const long offset;
** appropriate.
*/
static int
tzparse(name, sp, lastditch)
const char * name;
register struct state * const sp;
const int lastditch;
static int tzparse(const char *name, register struct state *sp, const int lastditch)
{
const char * stdname;
const char * dstname;
const char * dstname = NULL;
size_t stdlen;
size_t dstlen;
long stdoffset;
@ -717,7 +560,6 @@ const int lastditch;
register char * cp;
register int load_result;
INITIALIZE(dstname);
stdname = name;
if (lastditch) {
stdlen = strlen(name); /* length of standard zone name */
@ -913,83 +755,33 @@ const int lastditch;
return 0;
}
static void
gmtload(sp)
struct state * const sp;
static void gmtload(struct state *sp)
{
if (tzload(gmt, sp) != 0)
(void) tzparse(gmt, sp, TRUE);
}
#ifndef STD_INSPIRED
/*
** A non-static declaration of tzsetwall in a system header file
** may cause a warning about this upcoming static declaration...
*/
static
#endif /* !defined STD_INSPIRED */
void
tzsetwall P((void))
bool pg_tzset(const char *name)
{
if (lcl_is_set < 0)
return;
lcl_is_set = -1;
if (lcl_is_set && strcmp(lcl_TZname, name) == 0)
return true; /* no change */
#ifdef ALL_STATE
if (lclptr == NULL) {
lclptr = (struct state *) malloc(sizeof *lclptr);
if (lclptr == NULL) {
settzname(); /* all we can do */
return;
}
}
#endif /* defined ALL_STATE */
if (tzload((char *) NULL, lclptr) != 0)
gmtload(lclptr);
settzname();
}
if (strlen(name) >= sizeof(lcl_TZname))
return false; /* not gonna fit */
void
tzset P((void))
{
register const char * name;
name = getenv("TZ");
if (name == NULL) {
tzsetwall();
return;
}
if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
return;
lcl_is_set = strlen(name) < sizeof lcl_TZname;
if (lcl_is_set)
(void) strcpy(lcl_TZname, name);
#ifdef ALL_STATE
if (lclptr == NULL) {
lclptr = (struct state *) malloc(sizeof *lclptr);
if (lclptr == NULL) {
settzname(); /* all we can do */
return;
}
}
#endif /* defined ALL_STATE */
if (*name == '\0') {
/*
** User wants it fast rather than right.
*/
lclptr->leapcnt = 0; /* so, we're off a little */
lclptr->timecnt = 0;
lclptr->typecnt = 0;
lclptr->ttis[0].tt_isdst = 0;
lclptr->ttis[0].tt_gmtoff = 0;
lclptr->ttis[0].tt_abbrind = 0;
(void) strcpy(lclptr->chars, gmt);
} else if (tzload(name, lclptr) != 0)
if (tzload(name, lclptr) != 0) {
if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
(void) gmtload(lclptr);
settzname();
{
/* Unknown timezone. Fail our call instead of loading GMT! */
return false;
}
}
strcpy(lcl_TZname, name);
lcl_is_set = true;
return true;
}
/*
@ -1001,12 +793,7 @@ tzset P((void))
** The unused offset argument is for the benefit of mktime variants.
*/
/*ARGSUSED*/
static void
localsub(timep, offset, tmp)
const time_t * const timep;
const long offset;
struct tm * const tmp;
static void localsub(const time_t *timep, const long offset, struct pg_tm *tmp)
{
register struct state * sp;
register const struct ttinfo * ttisp;
@ -1014,12 +801,6 @@ struct tm * const tmp;
const time_t t = *timep;
sp = lclptr;
#ifdef ALL_STATE
if (sp == NULL) {
gmtsub(timep, offset, tmp);
return;
}
#endif /* defined ALL_STATE */
if (sp->timecnt == 0 || t < sp->ats[0]) {
i = 0;
while (sp->ttis[i].tt_isdst)
@ -1042,114 +823,47 @@ struct tm * const tmp;
*/
timesub(&t, ttisp->tt_gmtoff, sp, tmp);
tmp->tm_isdst = ttisp->tt_isdst;
tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
#ifdef TM_ZONE
tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
#endif /* defined TM_ZONE */
tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
}
struct tm *
localtime(timep)
const time_t * const timep;
struct pg_tm *pg_localtime(const time_t *timep)
{
tzset();
localsub(timep, 0L, &tm);
return &tm;
}
/*
** Re-entrant version of localtime.
*/
struct tm *
localtime_r(timep, tm)
const time_t * const timep;
struct tm * tm;
{
localsub(timep, 0L, tm);
return tm;
}
/*
** gmtsub is to gmtime as localsub is to localtime.
*/
static void
gmtsub(timep, offset, tmp)
const time_t * const timep;
const long offset;
struct tm * const tmp;
static void gmtsub(const time_t *timep, const long offset, struct pg_tm *tmp)
{
if (!gmt_is_set) {
gmt_is_set = TRUE;
#ifdef ALL_STATE
gmtptr = (struct state *) malloc(sizeof *gmtptr);
if (gmtptr != NULL)
#endif /* defined ALL_STATE */
gmtload(gmtptr);
}
timesub(timep, offset, gmtptr, tmp);
#ifdef TM_ZONE
/*
** Could get fancy here and deliver something such as
** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
** but this is no time for a treasure hunt.
*/
if (offset != 0)
tmp->TM_ZONE = wildabbr;
tmp->tm_zone = wildabbr;
else {
#ifdef ALL_STATE
if (gmtptr == NULL)
tmp->TM_ZONE = gmt;
else tmp->TM_ZONE = gmtptr->chars;
#endif /* defined ALL_STATE */
#ifndef ALL_STATE
tmp->TM_ZONE = gmtptr->chars;
#endif /* State Farm */
tmp->tm_zone = gmtptr->chars;
}
#endif /* defined TM_ZONE */
}
struct tm *
gmtime(timep)
const time_t * const timep;
struct pg_tm *pg_gmtime(const time_t *timep)
{
gmtsub(timep, 0L, &tm);
return &tm;
}
/*
* Re-entrant version of gmtime.
*/
struct tm *
gmtime_r(timep, tm)
const time_t * const timep;
struct tm * tm;
{
gmtsub(timep, 0L, tm);
return tm;
}
#ifdef STD_INSPIRED
struct tm *
offtime(timep, offset)
const time_t * const timep;
const long offset;
{
gmtsub(timep, offset, &tm);
return &tm;
}
#endif /* defined STD_INSPIRED */
static void
timesub(timep, offset, sp, tmp)
const time_t * const timep;
const long offset;
register const struct state * const sp;
register struct tm * const tmp;
static void timesub(const time_t *timep, const long offset, register const struct state *sp, register struct pg_tm *tmp)
{
register const struct lsinfo * lp;
register long days;
@ -1163,12 +877,7 @@ register struct tm * const tmp;
corr = 0;
hit = 0;
#ifdef ALL_STATE
i = (sp == NULL) ? 0 : sp->leapcnt;
#endif /* defined ALL_STATE */
#ifndef ALL_STATE
i = sp->leapcnt;
#endif /* State Farm */
while (--i >= 0) {
lp = &sp->lsis[i];
if (*timep >= lp->ls_trans) {
@ -1240,32 +949,7 @@ register struct tm * const tmp;
days = days - (long) ip[tmp->tm_mon];
tmp->tm_mday = (int) (days + 1);
tmp->tm_isdst = 0;
#ifdef TM_GMTOFF
tmp->TM_GMTOFF = offset;
#endif /* defined TM_GMTOFF */
}
char *
ctime(timep)
const time_t * const timep;
{
/*
** Section 4.12.3.2 of X3.159-1989 requires that
** The ctime function converts the calendar time pointed to by timer
** to local time in the form of a string. It is equivalent to
** asctime(localtime(timer))
*/
return asctime(localtime(timep));
}
char *
ctime_r(timep, buf)
const time_t * const timep;
char * buf;
{
struct tm tm;
return asctime_r(localtime_r(timep, &tm), buf);
tmp->tm_gmtoff = offset;
}
/*
@ -1278,18 +962,13 @@ char * buf;
** would still be very reasonable).
*/
#ifndef WRONG
#define WRONG (-1)
#endif /* !defined WRONG */
/*
** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com).
*/
static int
increment_overflow(number, delta)
int * number;
int delta;
static int increment_overflow(int *number, int delta)
{
int number0;
@ -1298,11 +977,7 @@ int delta;
return (*number < number0) != (delta < 0);
}
static int
normalize_overflow(tensptr, unitsptr, base)
int * const tensptr;
int * const unitsptr;
const int base;
static int normalize_overflow(int *tensptr, int *unitsptr, const int base)
{
register int tensdelta;
@ -1313,10 +988,7 @@ const int base;
return increment_overflow(tensptr, tensdelta);
}
static int
tmcomp(atmp, btmp)
register const struct tm * const atmp;
register const struct tm * const btmp;
static int tmcomp(register const struct pg_tm *atmp, register const struct pg_tm *btmp)
{
register int result;
@ -1329,13 +1001,7 @@ register const struct tm * const btmp;
return result;
}
static time_t
time2sub(tmp, funcp, offset, okayp, do_norm_secs)
struct tm * const tmp;
void (* const funcp) P((const time_t*, long, struct tm*));
const long offset;
int * const okayp;
const int do_norm_secs;
static time_t time2sub(struct pg_tm *tmp, void(*funcp)(const time_t *, long, struct pg_tm *), const long offset, int *okayp, const int do_norm_secs)
{
register const struct state * sp;
register int dir;
@ -1344,7 +1010,7 @@ const int do_norm_secs;
register int saved_seconds;
time_t newt;
time_t t;
struct tm yourtm, mytm;
struct pg_tm yourtm, mytm;
*okayp = FALSE;
yourtm = *tmp;
@ -1447,10 +1113,6 @@ const int do_norm_secs;
sp = (const struct state *)
(((void *) funcp == (void *) localsub) ?
lclptr : gmtptr);
#ifdef ALL_STATE
if (sp == NULL)
return WRONG;
#endif /* defined ALL_STATE */
for (i = sp->typecnt - 1; i >= 0; --i) {
if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
continue;
@ -1483,12 +1145,7 @@ label:
return t;
}
static time_t
time2(tmp, funcp, offset, okayp)
struct tm * const tmp;
void (* const funcp) P((const time_t*, long, struct tm*));
const long offset;
int * const okayp;
static time_t time2(struct pg_tm *tmp, void(*funcp)(const time_t*, long, struct pg_tm*), const long offset, int *okayp)
{
time_t t;
@ -1501,11 +1158,7 @@ int * const okayp;
return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
}
static time_t
time1(tmp, funcp, offset)
struct tm * const tmp;
void (* const funcp) P((const time_t *, long, struct tm *));
const long offset;
static time_t time1(struct pg_tm *tmp, void (*funcp)(const time_t *, long, struct pg_tm *), const long offset)
{
register time_t t;
register const struct state * sp;
@ -1520,22 +1173,11 @@ const long offset;
if (tmp->tm_isdst > 1)
tmp->tm_isdst = 1;
t = time2(tmp, funcp, offset, &okay);
#ifdef PCTS
/*
** PCTS code courtesy Grant Sullivan (grant@osf.org).
*/
if (okay)
return t;
if (tmp->tm_isdst < 0)
tmp->tm_isdst = 0; /* reset to std and try again */
#endif /* defined PCTS */
#ifndef PCTS
if (okay || tmp->tm_isdst < 0)
return t;
#endif /* !defined PCTS */
/*
** We're supposed to assume that somebody took a time of one type
** and did some math on it that yielded a "struct tm" that's bad.
** and did some math on it that yielded a "struct pg_tm" that's bad.
** We try to divine the type they started from and adjust to the
** type they need.
*/
@ -1544,10 +1186,6 @@ const long offset;
*/
sp = (const struct state *) (((void *) funcp == (void *) localsub) ?
lclptr : gmtptr);
#ifdef ALL_STATE
if (sp == NULL)
return WRONG;
#endif /* defined ALL_STATE */
for (i = 0; i < sp->typecnt; ++i)
seen[i] = FALSE;
nseen = 0;
@ -1578,135 +1216,17 @@ const long offset;
return WRONG;
}
time_t
mktime(tmp)
struct tm * const tmp;
time_t pg_mktime(struct pg_tm *tmp)
{
tzset();
return time1(tmp, localsub, 0L);
}
#ifdef STD_INSPIRED
time_t
timelocal(tmp)
struct tm * const tmp;
{
tmp->tm_isdst = -1; /* in case it wasn't initialized */
return mktime(tmp);
}
time_t
timegm(tmp)
struct tm * const tmp;
{
tmp->tm_isdst = 0;
return time1(tmp, gmtsub, 0L);
}
time_t
timeoff(tmp, offset)
struct tm * const tmp;
const long offset;
{
tmp->tm_isdst = 0;
return time1(tmp, gmtsub, offset);
}
#endif /* defined STD_INSPIRED */
#ifdef CMUCS
/*
** The following is supplied for compatibility with
** previous versions of the CMUCS runtime library.
* Return the name of the current timezone
*/
long
gtime(tmp)
struct tm * const tmp;
{
const time_t t = mktime(tmp);
if (t == WRONG)
return -1;
return t;
const char *
pg_get_current_timezone(void) {
if (lcl_is_set)
return lcl_TZname;
return NULL;
}
#endif /* defined CMUCS */
/*
** XXX--is the below the right way to conditionalize??
*/
#ifdef STD_INSPIRED
/*
** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
** is not the case if we are accounting for leap seconds.
** So, we provide the following conversion routines for use
** when exchanging timestamps with POSIX conforming systems.
*/
static long
leapcorr(timep)
time_t * timep;
{
register struct state * sp;
register struct lsinfo * lp;
register int i;
sp = lclptr;
i = sp->leapcnt;
while (--i >= 0) {
lp = &sp->lsis[i];
if (*timep >= lp->ls_trans)
return lp->ls_corr;
}
return 0;
}
time_t
time2posix(t)
time_t t;
{
tzset();
return t - leapcorr(&t);
}
time_t
posix2time(t)
time_t t;
{
time_t x;
time_t y;
tzset();
/*
** For a positive leap second hit, the result
** is not unique. For a negative leap second
** hit, the corresponding time doesn't exist,
** so we return an adjacent second.
*/
x = t + leapcorr(&t);
y = x - leapcorr(&x);
if (y < t) {
do {
x++;
y = x - leapcorr(&x);
} while (y < t);
if (t != y)
return x - 1;
} else if (y > t) {
do {
--x;
y = x - leapcorr(&x);
} while (y > t);
if (t != y)
return x + 1;
}
return x;
}
#endif /* defined STD_INSPIRED */

View File

@ -6,13 +6,22 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.9 2004/05/18 03:36:45 momjian Exp $
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.10 2004/05/21 05:08:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#define NO_REDEFINE_TIMEFUNCS
#include "postgres.h"
#include <ctype.h>
#include "miscadmin.h"
#include "pgtime.h"
#include "pgtz.h"
#include "tzfile.h"
#include "utils/elog.h"
#include "utils/guc.h"
static char tzdir[MAXPGPATH];
@ -30,3 +39,255 @@ pg_TZDIR(void)
done_tzdir = 1;
return tzdir;
}
/*
* Try to determine the system timezone (as opposed to the timezone
* set in our own library).
*/
#define T_YEAR (60*60*24*365)
#define T_MONTH (60*60*24*30)
struct tztry {
time_t std_t,dst_t;
char std_time[TZ_STRLEN_MAX+1],dst_time[TZ_STRLEN_MAX+1];
int std_ofs,dst_ofs;
struct tm std_tm, dst_tm;
};
static bool compare_tm(struct tm *s, struct pg_tm *p) {
if (s->tm_sec != p->tm_sec ||
s->tm_min != p->tm_min ||
s->tm_hour != p->tm_hour ||
s->tm_mday != p->tm_mday ||
s->tm_mon != p->tm_mon ||
s->tm_year != p->tm_year ||
s->tm_wday != p->tm_wday ||
s->tm_yday != p->tm_yday ||
s->tm_isdst != p->tm_isdst)
return false;
return true;
}
static bool try_timezone(char *tzname, struct tztry *tt, bool checkdst) {
struct pg_tm *pgtm;
if (!pg_tzset(tzname))
return false; /* If this timezone couldn't be picked at all */
/* Verify standard time */
pgtm = pg_localtime(&(tt->std_t));
if (!pgtm)
return false;
if (!compare_tm(&(tt->std_tm), pgtm))
return false;
if (!checkdst)
return true;
/* Now check daylight time */
pgtm = pg_localtime(&(tt->dst_t));
if (!pgtm)
return false;
if (!compare_tm(&(tt->dst_tm), pgtm))
return false;
return true;
}
static int get_timezone_offset(struct tm *tm) {
#if defined(HAVE_STRUCT_TM_TM_ZONE)
return tm->tm_gmtoff;
#elif defined(HAVE_INT_TIMEZONE)
#ifdef HAVE_UNDERSCORE_TIMEZONE
return -_timezone;
#else
return -timezone;
#endif
#else
#error No way to determine TZ? Can this happen?
#endif
}
#ifdef WIN32
#define TZABBREV(tz) win32_get_timezone_abbrev(tz)
static char *win32_get_timezone_abbrev(char *tz) {
static char w32tzabbr[TZ_STRLEN_MAX+1];
int l = 0;
char *c;
for (c = tz; *c; c++) {
if (isupper(*c))
w32tzabbr[l++] = *c;
}
w32tzabbr[l] = '\0';
return w32tzabbr;
}
#else
#define TZABBREV(tz) tz
#endif
/*
* Try to identify a timezone name (in our terminology) that matches the
* observed behavior of the system timezone library. We cannot assume that
* the system TZ environment setting (if indeed there is one) matches our
* terminology, so ignore it and just look at what localtime() returns.
*/
static char *
identify_system_timezone(void)
{
static char __tzbuf[TZ_STRLEN_MAX+1];
bool std_found=false,
dst_found=false;
time_t tnow = time(NULL);
time_t t;
struct tztry tt;
char cbuf[TZ_STRLEN_MAX+1];
/* Initialize OS timezone library */
tzset();
memset(&tt, 0, sizeof(tt));
for (t = tnow; t < tnow+T_YEAR; t += T_MONTH) {
struct tm *tm = localtime(&t);
if (tm->tm_isdst == 0 && !std_found) {
/* Standard time */
memcpy(&tt.std_tm, tm, sizeof(struct tm));
memset(cbuf,0,sizeof(cbuf));
strftime(cbuf, sizeof(cbuf)-1, "%Z", tm); /* zone abbr */
strcpy(tt.std_time, TZABBREV(cbuf));
tt.std_ofs = get_timezone_offset(tm);
tt.std_t = t;
std_found = true;
}
else if (tm->tm_isdst == 1 && !dst_found) {
/* Daylight time */
memcpy(&tt.dst_tm, tm, sizeof(struct tm));
memset(cbuf,0,sizeof(cbuf));
strftime(cbuf, sizeof(cbuf)-1, "%Z", tm); /* zone abbr */
strcpy(tt.dst_time, TZABBREV(cbuf));
tt.dst_ofs = get_timezone_offset(tm);
tt.dst_t = t;
dst_found = true;
}
if (std_found && dst_found)
break; /* Got both standard and daylight */
}
if (!std_found)
{
/* Failed to determine TZ! */
ereport(LOG,
(errmsg("unable to determine system timezone, defaulting to \"%s\"", "GMT"),
errhint("You can specify the correct timezone in postgresql.conf.")));
return NULL; /* go to GMT */
}
if (dst_found) {
/* Try STD<ofs>DST */
sprintf(__tzbuf,"%s%d%s",tt.std_time,-tt.std_ofs/3600,tt.dst_time);
if (try_timezone(__tzbuf, &tt, dst_found))
return __tzbuf;
}
/* Try just the STD timezone */
strcpy(__tzbuf,tt.std_time);
if (try_timezone(__tzbuf, &tt, dst_found))
return __tzbuf;
/* Did not find the timezone. Fallback to try a GMT zone. */
sprintf(__tzbuf,"Etc/GMT%s%d",
(-tt.std_ofs<0)?"+":"",tt.std_ofs/3600);
ereport(LOG,
(errmsg("could not recognize system timezone, defaulting to \"%s\"",
__tzbuf),
errhint("You can specify the correct timezone in postgresql.conf.")));
return __tzbuf;
}
/*
* Check whether timezone is acceptable.
*
* What we are doing here is checking for leap-second-aware timekeeping.
* We need to reject such TZ settings because they'll wreak havoc with our
* date/time arithmetic.
*
* NB: this must NOT ereport(ERROR). The caller must get control back so that
* it can restore the old value of TZ if we don't like the new one.
*/
bool
tz_acceptable(void)
{
struct pg_tm tt;
time_t time2000;
/*
* To detect leap-second timekeeping, compute the time_t value for
* local midnight, 2000-01-01. Insist that this be a multiple of 60;
* any partial-minute offset has to be due to leap seconds.
*/
MemSet(&tt, 0, sizeof(tt));
tt.tm_year = 100;
tt.tm_mon = 0;
tt.tm_mday = 1;
tt.tm_isdst = -1;
time2000 = pg_mktime(&tt);
if ((time2000 % 60) != 0)
return false;
return true;
}
/*
* Identify a suitable default timezone setting based on the environment,
* and make it active.
*
* We first look to the TZ environment variable. If not found or not
* recognized by our own code, we see if we can identify the timezone
* from the behavior of the system timezone library. When all else fails,
* fall back to GMT.
*/
const char *
select_default_timezone(void)
{
char *def_tz;
def_tz = getenv("TZ");
if (def_tz && pg_tzset(def_tz) && tz_acceptable())
return def_tz;
def_tz = identify_system_timezone();
if (def_tz && pg_tzset(def_tz) && tz_acceptable())
return def_tz;
if (pg_tzset("GMT") && tz_acceptable())
return "GMT";
ereport(FATAL,
(errmsg("could not select a suitable default timezone"),
errdetail("It appears that your GMT time zone uses leap seconds. PostgreSQL does not support leap seconds.")));
return NULL; /* keep compiler quiet */
}
/*
* Initialize timezone library
*
* This is called after initial loading of postgresql.conf. If no TimeZone
* setting was found therein, we try to derive one from the environment.
*/
void pg_timezone_initialize(void) {
/* Do we need to try to figure the timezone? */
if (strcmp(GetConfigOption("timezone"), "UNKNOWN") == 0) {
const char *def_tz;
/* Select setting */
def_tz = select_default_timezone();
/* Tell GUC about the value. Will redundantly call pg_tzset() */
SetConfigOption("timezone", def_tz, PGC_POSTMASTER, PGC_S_ENV_VAR);
}
}

View File

@ -1,12 +1,23 @@
#include "postgres.h"
#include "miscadmin.h"
/*-------------------------------------------------------------------------
*
* pgtz.h
* Timezone Library Integration Functions
*
* Note: this file contains only definitions that are private to the
* timezone library. Public definitions are in pgtime.h.
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/pgtz.h,v 1.7 2004/05/21 05:08:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef _PGTZ_H
#define _PGTZ_H
#ifndef HAVE_SYMLINK
#define HAVE_SYMLINK 0
#endif
#define TZ_STRLEN_MAX 255
extern char *pg_TZDIR(void);
#define NOID
#define TZDIR pg_TZDIR()
char *pg_TZDIR(void);
#endif /* _PGTZ_H */

View File

@ -1,5 +1,4 @@
#ifndef PRIVATE_H
#define PRIVATE_H
/*
@ -15,94 +14,12 @@
** Thank you!
*/
/*
** ID
*/
#ifndef lint
#ifndef NOID
static char privatehid[] = "@(#)private.h 7.53";
#endif /* !defined NOID */
#endif /* !defined lint */
/*
** Defaults for preprocessor symbols.
** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'.
*/
#ifndef HAVE_ADJTIME
#define HAVE_ADJTIME 1
#endif /* !defined HAVE_ADJTIME */
#ifndef HAVE_GETTEXT
#define HAVE_GETTEXT 0
#endif /* !defined HAVE_GETTEXT */
#ifndef HAVE_INCOMPATIBLE_CTIME_R
#define HAVE_INCOMPATIBLE_CTIME_R 0
#endif /* !defined INCOMPATIBLE_CTIME_R */
#ifndef HAVE_SETTIMEOFDAY
#define HAVE_SETTIMEOFDAY 3
#endif /* !defined HAVE_SETTIMEOFDAY */
#ifndef HAVE_STRERROR
#define HAVE_STRERROR 1
#endif /* !defined HAVE_STRERROR */
#ifndef HAVE_SYMLINK
#define HAVE_SYMLINK 1
#endif /* !defined HAVE_SYMLINK */
#ifndef HAVE_SYS_STAT_H
#define HAVE_SYS_STAT_H 1
#endif /* !defined HAVE_SYS_STAT_H */
#ifndef HAVE_SYS_WAIT_H
#define HAVE_SYS_WAIT_H 1
#endif /* !defined HAVE_SYS_WAIT_H */
#ifndef HAVE_UNISTD_H
#define HAVE_UNISTD_H 1
#endif /* !defined HAVE_UNISTD_H */
#ifndef HAVE_UTMPX_H
#define HAVE_UTMPX_H 0
#endif /* !defined HAVE_UTMPX_H */
#ifndef LOCALE_HOME
#define LOCALE_HOME "/usr/lib/locale"
#endif /* !defined LOCALE_HOME */
#if HAVE_INCOMPATIBLE_CTIME_R
#define asctime_r _incompatible_asctime_r
#define ctime_r _incompatible_ctime_r
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
/*
** Nested includes
*/
#include "sys/types.h" /* for time_t */
#include "stdio.h"
#include "errno.h"
#include "string.h"
#include "limits.h" /* for CHAR_BIT */
#define save_timezone pg_timezone
#undef timezone
#include "time.h"
#define timezone save_timezone
#include "stdlib.h"
#if HAVE_GETTEXT - 0
#include "libintl.h"
#endif /* HAVE_GETTEXT - 0 */
#if HAVE_SYS_WAIT_H - 0
#include <limits.h> /* for CHAR_BIT */
#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
#endif /* HAVE_SYS_WAIT_H - 0 */
#include <unistd.h> /* for F_OK and R_OK */
#include "pgtime.h"
#ifndef WIFEXITED
#define WIFEXITED(status) (((status) & 0xff) == 0)
@ -111,39 +28,9 @@ static char privatehid[] = "@(#)private.h 7.53";
#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
#endif /* !defined WEXITSTATUS */
#if HAVE_UNISTD_H - 0
#include "unistd.h" /* for F_OK and R_OK */
#endif /* HAVE_UNISTD_H - 0 */
#if !(HAVE_UNISTD_H - 0)
#ifndef F_OK
#define F_OK 0
#endif /* !defined F_OK */
#ifndef R_OK
#define R_OK 4
#endif /* !defined R_OK */
#endif /* !(HAVE_UNISTD_H - 0) */
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
/*
** Workarounds for compilers/systems.
*/
/*
** SunOS 4.1.1 cc lacks prototypes.
*/
#ifndef P
#ifdef __STDC__
#define P(x) x
#endif /* defined __STDC__ */
#ifndef __STDC__
#define P(x) ()
#endif /* !defined __STDC__ */
#endif /* !defined P */
/*
** SunOS 4.1.1 headers lack EXIT_SUCCESS.
*/
@ -160,60 +47,30 @@ static char privatehid[] = "@(#)private.h 7.53";
#define EXIT_FAILURE 1
#endif /* !defined EXIT_FAILURE */
/*
** SunOS 4.1.1 headers lack FILENAME_MAX.
*/
#ifndef FILENAME_MAX
#ifndef MAXPATHLEN
#ifdef unix
#include "sys/param.h"
#endif /* defined unix */
#endif /* !defined MAXPATHLEN */
#ifdef MAXPATHLEN
#define FILENAME_MAX MAXPATHLEN
#endif /* defined MAXPATHLEN */
#ifndef MAXPATHLEN
#define FILENAME_MAX 1024 /* Pure guesswork */
#endif /* !defined MAXPATHLEN */
#endif /* !defined FILENAME_MAX */
/*
** SunOS 4.1.1 libraries lack remove.
*/
#ifndef remove
extern int unlink P((const char * filename));
extern int unlink (const char * filename);
#define remove unlink
#endif /* !defined remove */
/*
** Some ancient errno.h implementations don't declare errno.
** But some newer errno.h implementations define it as a macro.
** Fix the former without affecting the latter.
* Private function declarations.
*/
#ifndef errno
extern int errno;
#endif /* !defined errno */
/*
** Private function declarations.
*/
char * icalloc P((int nelem, int elsize));
char * icatalloc P((char * old, const char * new));
char * icpyalloc P((const char * string));
char * imalloc P((int n));
void * irealloc P((void * pointer, int size));
void icfree P((char * pointer));
void ifree P((char * pointer));
char * scheck P((const char *string, const char *format));
extern char *icalloc (int nelem, int elsize);
extern char *icatalloc (char *old, const char *new);
extern char *icpyalloc (const char *string);
extern char *imalloc (int n);
extern void *irealloc (void *pointer, int size);
extern void icfree (char *pointer);
extern void ifree (char *pointer);
extern char *scheck (const char *string, const char *format);
/*
** Finally, some convenience items.
* Finally, some convenience items.
*/
#ifndef TRUE
@ -243,54 +100,7 @@ char * scheck P((const char *string, const char *format));
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type))
#endif /* !defined INT_STRLEN_MAXIMUM */
/*
** INITIALIZE(x)
*/
#ifndef GNUC_or_lint
#ifdef lint
#define GNUC_or_lint
#endif /* defined lint */
#ifndef lint
#ifdef __GNUC__
#define GNUC_or_lint
#endif /* defined __GNUC__ */
#endif /* !defined lint */
#endif /* !defined GNUC_or_lint */
#ifndef INITIALIZE
#ifdef GNUC_or_lint
#define INITIALIZE(x) ((x) = 0)
#endif /* defined GNUC_or_lint */
#ifndef GNUC_or_lint
#define INITIALIZE(x)
#endif /* !defined GNUC_or_lint */
#endif /* !defined INITIALIZE */
/*
** For the benefit of GNU folk...
** `_(MSGID)' uses the current locale's message library string for MSGID.
** The default is to use gettext if available, and use MSGID otherwise.
*/
#ifndef _
#if HAVE_GETTEXT - 0
#define _(msgid) gettext(msgid)
#else /* !(HAVE_GETTEXT - 0) */
#define _(msgid) msgid
#endif /* !(HAVE_GETTEXT - 0) */
#endif /* !defined _ */
#ifndef TZ_DOMAIN
#define TZ_DOMAIN "tz"
#endif /* !defined TZ_DOMAIN */
#if HAVE_INCOMPATIBLE_CTIME_R
#undef asctime_r
#undef ctime_r
char *asctime_r P((struct tm const *, char *));
char *ctime_r P((time_t const *, char *));
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
#define _(msgid) (msgid)
/*
** UNIX was a registered trademark of The Open Group in 2003.

View File

@ -1,17 +1,9 @@
#ifndef lint
#ifndef NOID
static char elsieid[] = "@(#)scheck.c 8.15";
#endif /* !defined lint */
#endif /* !defined NOID */
/*LINTLIBRARY*/
#include "postgres.h"
#include "private.h"
char *
scheck(string, format)
const char * const string;
const char * const format;
char *scheck(const char *string, const char *format)
{
register char * fbuf;
register const char * fp;

480
src/timezone/strftime.c Normal file
View File

@ -0,0 +1,480 @@
/*
** Copyright (c) 1989 The Regents of the University of California.
** All rights reserved.
**
** Redistribution and use in source and binary forms are permitted
** provided that the above copyright notice and this paragraph are
** duplicated in all such forms and that any documentation,
** advertising materials, and other materials related to such
** distribution and use acknowledge that the software was developed
** by the University of California, Berkeley. The name of the
** University may not be used to endorse or promote products derived
** from this software without specific prior written permission.
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "postgres.h"
#include <fcntl.h>
#include <locale.h>
#include "pgtz.h"
#include "private.h"
#include "tzfile.h"
struct lc_time_T {
const char * mon[MONSPERYEAR];
const char * month[MONSPERYEAR];
const char * wday[DAYSPERWEEK];
const char * weekday[DAYSPERWEEK];
const char * X_fmt;
const char * x_fmt;
const char * c_fmt;
const char * am;
const char * pm;
const char * date_fmt;
};
#define Locale (&C_time_locale)
static const struct lc_time_T C_time_locale = {
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
}, {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
}, {
"Sun", "Mon", "Tue", "Wed",
"Thu", "Fri", "Sat"
}, {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
},
/* X_fmt */
"%H:%M:%S",
/*
** x_fmt
** C99 requires this format.
** Using just numbers (as here) makes Quakers happier;
** it's also compatible with SVR4.
*/
"%m/%d/%y",
/*
** c_fmt
** C99 requires this format.
** Previously this code used "%D %X", but we now conform to C99.
** Note that
** "%a %b %d %H:%M:%S %Y"
** is used by Solaris 2.3.
*/
"%a %b %e %T %Y",
/* am */
"AM",
/* pm */
"PM",
/* date_fmt */
"%a %b %e %H:%M:%S %Z %Y"
};
static char * _add (const char *, char *, const char *);
static char * _conv (int, const char *, char *, const char *);
static char * _fmt (const char *, const struct pg_tm *, char *, const char *, int *);
#define IN_NONE 0
#define IN_SOME 1
#define IN_THIS 2
#define IN_ALL 3
size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
{
char * p;
int warn;
warn = IN_NONE;
p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
if (p == s + maxsize)
return 0;
*p = '\0';
return p - s;
}
static char * _fmt(const char *format, const struct pg_tm *t, char *pt, const char *ptlim, int *warnp)
{
for ( ; *format; ++format) {
if (*format == '%') {
label:
switch (*++format) {
case '\0':
--format;
break;
case 'A':
pt = _add((t->tm_wday < 0 ||
t->tm_wday >= DAYSPERWEEK) ?
"?" : Locale->weekday[t->tm_wday],
pt, ptlim);
continue;
case 'a':
pt = _add((t->tm_wday < 0 ||
t->tm_wday >= DAYSPERWEEK) ?
"?" : Locale->wday[t->tm_wday],
pt, ptlim);
continue;
case 'B':
pt = _add((t->tm_mon < 0 ||
t->tm_mon >= MONSPERYEAR) ?
"?" : Locale->month[t->tm_mon],
pt, ptlim);
continue;
case 'b':
case 'h':
pt = _add((t->tm_mon < 0 ||
t->tm_mon >= MONSPERYEAR) ?
"?" : Locale->mon[t->tm_mon],
pt, ptlim);
continue;
case 'C':
/*
** %C used to do a...
** _fmt("%a %b %e %X %Y", t);
** ...whereas now POSIX 1003.2 calls for
** something completely different.
** (ado, 1993-05-24)
*/
pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
"%02d", pt, ptlim);
continue;
case 'c':
{
int warn2 = IN_SOME;
pt = _fmt(Locale->c_fmt, t, pt, ptlim, warnp);
if (warn2 == IN_ALL)
warn2 = IN_THIS;
if (warn2 > *warnp)
*warnp = warn2;
}
continue;
case 'D':
pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
continue;
case 'd':
pt = _conv(t->tm_mday, "%02d", pt, ptlim);
continue;
case 'E':
case 'O':
/*
** C99 locale modifiers.
** The sequences
** %Ec %EC %Ex %EX %Ey %EY
** %Od %oe %OH %OI %Om %OM
** %OS %Ou %OU %OV %Ow %OW %Oy
** are supposed to provide alternate
** representations.
*/
goto label;
case 'e':
pt = _conv(t->tm_mday, "%2d", pt, ptlim);
continue;
case 'F':
pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
continue;
case 'H':
pt = _conv(t->tm_hour, "%02d", pt, ptlim);
continue;
case 'I':
pt = _conv((t->tm_hour % 12) ?
(t->tm_hour % 12) : 12,
"%02d", pt, ptlim);
continue;
case 'j':
pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim);
continue;
case 'k':
/*
** This used to be...
** _conv(t->tm_hour % 12 ?
** t->tm_hour % 12 : 12, 2, ' ');
** ...and has been changed to the below to
** match SunOS 4.1.1 and Arnold Robbins'
** strftime version 3.0. That is, "%k" and
** "%l" have been swapped.
** (ado, 1993-05-24)
*/
pt = _conv(t->tm_hour, "%2d", pt, ptlim);
continue;
#ifdef KITCHEN_SINK
case 'K':
/*
** After all this time, still unclaimed!
*/
pt = _add("kitchen sink", pt, ptlim);
continue;
#endif /* defined KITCHEN_SINK */
case 'l':
/*
** This used to be...
** _conv(t->tm_hour, 2, ' ');
** ...and has been changed to the below to
** match SunOS 4.1.1 and Arnold Robbin's
** strftime version 3.0. That is, "%k" and
** "%l" have been swapped.
** (ado, 1993-05-24)
*/
pt = _conv((t->tm_hour % 12) ?
(t->tm_hour % 12) : 12,
"%2d", pt, ptlim);
continue;
case 'M':
pt = _conv(t->tm_min, "%02d", pt, ptlim);
continue;
case 'm':
pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim);
continue;
case 'n':
pt = _add("\n", pt, ptlim);
continue;
case 'p':
pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
Locale->pm :
Locale->am,
pt, ptlim);
continue;
case 'R':
pt = _fmt("%H:%M", t, pt, ptlim, warnp);
continue;
case 'r':
pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
continue;
case 'S':
pt = _conv(t->tm_sec, "%02d", pt, ptlim);
continue;
case 's':
{
struct pg_tm tm;
char buf[INT_STRLEN_MAXIMUM(time_t) + 1];
time_t mkt;
tm = *t;
mkt = pg_mktime(&tm);
if (TYPE_SIGNED(time_t))
(void) sprintf(buf, "%ld", (long) mkt);
else
(void) sprintf(buf, "%lu", (unsigned long) mkt);
pt = _add(buf, pt, ptlim);
}
continue;
case 'T':
pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
continue;
case 't':
pt = _add("\t", pt, ptlim);
continue;
case 'U':
pt = _conv((t->tm_yday + DAYSPERWEEK -
t->tm_wday) / DAYSPERWEEK,
"%02d", pt, ptlim);
continue;
case 'u':
/*
** From Arnold Robbins' strftime version 3.0:
** "ISO 8601: Weekday as a decimal number
** [1 (Monday) - 7]"
** (ado, 1993-05-24)
*/
pt = _conv((t->tm_wday == 0) ?
DAYSPERWEEK : t->tm_wday,
"%d", pt, ptlim);
continue;
case 'V': /* ISO 8601 week number */
case 'G': /* ISO 8601 year (four digits) */
case 'g': /* ISO 8601 year (two digits) */
/*
** From Arnold Robbins' strftime version 3.0: "the week number of the
** year (the first Monday as the first day of week 1) as a decimal number
** (01-53)."
** (ado, 1993-05-24)
**
** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
** "Week 01 of a year is per definition the first week which has the
** Thursday in this year, which is equivalent to the week which contains
** the fourth day of January. In other words, the first week of a new year
** is the week which has the majority of its days in the new year. Week 01
** might also contain days from the previous year and the week before week
** 01 of a year is the last week (52 or 53) of the previous year even if
** it contains days from the new year. A week starts with Monday (day 1)
** and ends with Sunday (day 7). For example, the first week of the year
** 1997 lasts from 1996-12-30 to 1997-01-05..."
** (ado, 1996-01-02)
*/
{
int year;
int yday;
int wday;
int w;
year = t->tm_year + TM_YEAR_BASE;
yday = t->tm_yday;
wday = t->tm_wday;
for ( ; ; ) {
int len;
int bot;
int top;
len = isleap(year) ?
DAYSPERLYEAR :
DAYSPERNYEAR;
/*
** What yday (-3 ... 3) does
** the ISO year begin on?
*/
bot = ((yday + 11 - wday) %
DAYSPERWEEK) - 3;
/*
** What yday does the NEXT
** ISO year begin on?
*/
top = bot -
(len % DAYSPERWEEK);
if (top < -3)
top += DAYSPERWEEK;
top += len;
if (yday >= top) {
++year;
w = 1;
break;
}
if (yday >= bot) {
w = 1 + ((yday - bot) /
DAYSPERWEEK);
break;
}
--year;
yday += isleap(year) ?
DAYSPERLYEAR :
DAYSPERNYEAR;
}
if (*format == 'V')
pt = _conv(w, "%02d",
pt, ptlim);
else if (*format == 'g') {
*warnp = IN_ALL;
pt = _conv(year % 100, "%02d",
pt, ptlim);
} else pt = _conv(year, "%04d",
pt, ptlim);
}
continue;
case 'v':
/*
** From Arnold Robbins' strftime version 3.0:
** "date as dd-bbb-YYYY"
** (ado, 1993-05-24)
*/
pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
continue;
case 'W':
pt = _conv((t->tm_yday + DAYSPERWEEK -
(t->tm_wday ?
(t->tm_wday - 1) :
(DAYSPERWEEK - 1))) / DAYSPERWEEK,
"%02d", pt, ptlim);
continue;
case 'w':
pt = _conv(t->tm_wday, "%d", pt, ptlim);
continue;
case 'X':
pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
continue;
case 'x':
{
int warn2 = IN_SOME;
pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
if (warn2 == IN_ALL)
warn2 = IN_THIS;
if (warn2 > *warnp)
*warnp = warn2;
}
continue;
case 'y':
*warnp = IN_ALL;
pt = _conv((t->tm_year + TM_YEAR_BASE) % 100,
"%02d", pt, ptlim);
continue;
case 'Y':
pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d",
pt, ptlim);
continue;
case 'Z':
if (t->tm_zone != NULL)
pt = _add(t->tm_zone, pt, ptlim);
/*
** C99 says that %Z must be replaced by the
** empty string if the time zone is not
** determinable.
*/
continue;
case 'z':
{
int diff;
char const * sign;
if (t->tm_isdst < 0)
continue;
diff = t->tm_gmtoff;
if (diff < 0) {
sign = "-";
diff = -diff;
} else sign = "+";
pt = _add(sign, pt, ptlim);
diff /= 60;
pt = _conv((diff/60)*100 + diff%60,
"%04d", pt, ptlim);
}
continue;
case '+':
pt = _fmt(Locale->date_fmt, t, pt, ptlim,
warnp);
continue;
case '%':
/*
** X311J/88-090 (4.12.3.5): if conversion char is
** undefined, behavior is undefined. Print out the
** character itself as printf(3) also does.
*/
default:
break;
}
}
if (pt == ptlim)
break;
*pt++ = *format;
}
return pt;
}
static char * _conv(const int n, const char *format, char *pt, const char *ptlim)
{
char buf[INT_STRLEN_MAXIMUM(int) + 1];
(void) sprintf(buf, format, n);
return _add(buf, pt, ptlim);
}
static char *_add(const char *str, char *pt, const char *ptlim)
{
while (pt < ptlim && (*pt = *str++) != '\0')
++pt;
return pt;
}

View File

@ -15,31 +15,12 @@
** Thank you!
*/
/*
** ID
*/
#ifndef lint
#ifndef NOID
static char tzfilehid[] = "@(#)tzfile.h 7.14";
#endif /* !defined NOID */
#endif /* !defined lint */
/*
** Information about time zone files.
*/
#ifndef TZDIR
#define TZDIR "/usr/local/etc/zoneinfo" /* Time zone object file directory */
#endif /* !defined TZDIR */
#ifndef TZDEFAULT
#define TZDEFAULT "localtime"
#endif /* !defined TZDEFAULT */
#ifndef TZDEFRULES
#define TZDEFRULES "posixrules"
#endif /* !defined TZDEFRULES */
/*
** Each file begins with. . .
@ -88,7 +69,6 @@ struct tzhead {
** exceed any of the limits below.
*/
#ifndef TZ_MAX_TIMES
/*
** The TZ_MAX_TIMES value below is enough to handle a bit more than a
** year's worth of solar time (corrected daily to the nearest second) or
@ -96,29 +76,13 @@ struct tzhead {
** (where there are three time zone transitions every fourth year).
*/
#define TZ_MAX_TIMES 370
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
#ifndef NOSOLAR
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
#endif /* !defined NOSOLAR */
#ifdef NOSOLAR
/*
** Must be at least 14 for Europe/Riga as of Jan 12 1995,
** as noted by Earl Chew <earl@hpato.aus.hp.com>.
*/
#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
#endif /* !defined NOSOLAR */
#endif /* !defined TZ_MAX_TYPES */
#ifndef TZ_MAX_CHARS
#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
/* (limited by what unsigned chars can hold) */
#endif /* !defined TZ_MAX_CHARS */
#ifndef TZ_MAX_LEAPS
#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
#endif /* !defined TZ_MAX_LEAPS */
#define SECSPERMIN 60
#define MINSPERHOUR 60
@ -163,26 +127,4 @@ struct tzhead {
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
#ifndef USG
/*
** Use of the underscored variants may cause problems if you move your code to
** certain System-V-based systems; for maximum portability, use the
** underscore-free variants. The underscored variants are provided for
** backward compatibility only; they may disappear from future versions of
** this file.
*/
#define SECS_PER_MIN SECSPERMIN
#define MINS_PER_HOUR MINSPERHOUR
#define HOURS_PER_DAY HOURSPERDAY
#define DAYS_PER_WEEK DAYSPERWEEK
#define DAYS_PER_NYEAR DAYSPERNYEAR
#define DAYS_PER_LYEAR DAYSPERLYEAR
#define SECS_PER_HOUR SECSPERHOUR
#define SECS_PER_DAY SECSPERDAY
#define MONS_PER_YEAR MONSPERYEAR
#endif /* !defined USG */
#endif /* !defined TZFILE_H */

View File

@ -1,19 +1,20 @@
static char elsieid[] = "@(#)zic.c 7.115";
#include "postgres.h"
#include <locale.h>
#include "pgtz.h"
#undef unlink
#undef TZDIR
#define TZDIR "data"
#include "private.h"
#include "tzfile.h"
#ifdef WIN32
#undef unlink
#include <windows.h>
#endif
#include "private.h"
#include "locale.h"
#include "tzfile.h"
#if HAVE_SYS_STAT_H
#include "sys/stat.h"
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifndef WIN32
#ifdef S_IRUSR
#define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
@ -22,11 +23,7 @@ static char elsieid[] = "@(#)zic.c 7.115";
#endif
#endif
/*
* This allows zic to compile by just assigning a dummy value.
* pgtz.c references it, but no one uses it from zic.
*/
char my_exec_path[MAXPGPATH] = "";
static char elsieid[] = "@(#)zic.c 7.115";
/*
** On some ancient hosts, predicates like `isspace(C)' are defined
@ -36,7 +33,7 @@ char my_exec_path[MAXPGPATH] = "";
** For portability, we check both ancient and modern requirements.
** If isascii is not defined, the isascii check succeeds trivially.
*/
#include "ctype.h"
#include <ctype.h>
#ifndef isascii
#define isascii(x) 1
#endif
@ -94,62 +91,57 @@ struct zone {
time_t z_untiltime;
};
extern int getopt P((int argc, char * const argv[],
const char * options));
extern int link P((const char * fromname, const char * toname));
extern char * optarg;
extern int optind;
static void addtt P((time_t starttime, int type));
static int addtype P((long gmtoff, const char * abbr, int isdst,
int ttisstd, int ttisgmt));
static void leapadd P((time_t t, int positive, int rolling, int count));
static void adjleap P((void));
static void associate P((void));
static int ciequal P((const char * ap, const char * bp));
static void convert P((long val, char * buf));
static void dolink P((const char * fromfile, const char * tofile));
static void doabbr P((char * abbr, const char * format,
const char * letters, int isdst));
static void eat P((const char * name, int num));
static void eats P((const char * name, int num,
const char * rname, int rnum));
static long eitol P((int i));
static void error P((const char * message));
static char ** getfields P((char * buf));
static long gethms P((const char * string, const char * errstrng,
int signable));
static void infile P((const char * filename));
static void inleap P((char ** fields, int nfields));
static void inlink P((char ** fields, int nfields));
static void inrule P((char ** fields, int nfields));
static int inzcont P((char ** fields, int nfields));
static int inzone P((char ** fields, int nfields));
static int inzsub P((char ** fields, int nfields, int iscont));
static int itsabbr P((const char * abbr, const char * word));
static int itsdir P((const char * name));
static int lowerit P((int c));
static char * memcheck P((char * tocheck));
static int mkdirs P((char * filename));
static void newabbr P((const char * abbr));
static long oadd P((long t1, long t2));
static void outzone P((const struct zone * zp, int ntzones));
static void puttzcode P((long code, FILE * fp));
static int rcomp P((const void * leftp, const void * rightp));
static time_t rpytime P((const struct rule * rp, int wantedy));
static void rulesub P((struct rule * rp,
extern int link (const char * fromname, const char * toname);
static void addtt (time_t starttime, int type);
static int addtype (long gmtoff, const char * abbr, int isdst,
int ttisstd, int ttisgmt);
static void leapadd (time_t t, int positive, int rolling, int count);
static void adjleap (void);
static void associate (void);
static int ciequal (const char * ap, const char * bp);
static void convert (long val, char * buf);
static void dolink (const char * fromfile, const char * tofile);
static void doabbr (char * abbr, const char * format,
const char * letters, int isdst);
static void eat (const char * name, int num);
static void eats (const char * name, int num,
const char * rname, int rnum);
static long eitol (int i);
static void error (const char * message);
static char ** getfields (char * buf);
static long gethms (const char * string, const char * errstrng,
int signable);
static void infile (const char * filename);
static void inleap (char ** fields, int nfields);
static void inlink (char ** fields, int nfields);
static void inrule (char ** fields, int nfields);
static int inzcont (char ** fields, int nfields);
static int inzone (char ** fields, int nfields);
static int inzsub (char ** fields, int nfields, int iscont);
static int itsabbr (const char * abbr, const char * word);
static int itsdir (const char * name);
static int lowerit (int c);
static char * memcheck (char * tocheck);
static int mkdirs (char * filename);
static void newabbr (const char * abbr);
static long oadd (long t1, long t2);
static void outzone (const struct zone * zp, int ntzones);
static void puttzcode (long code, FILE * fp);
static int rcomp (const void * leftp, const void * rightp);
static time_t rpytime (const struct rule * rp, int wantedy);
static void rulesub (struct rule * rp,
const char * loyearp, const char * hiyearp,
const char * typep, const char * monthp,
const char * dayp, const char * timep));
static void setboundaries P((void));
static time_t tadd P((time_t t1, long t2));
static void usage P((void));
static void writezone P((const char * name));
static int yearistype P((int year, const char * type));
const char * dayp, const char * timep);
static void setboundaries (void);
static time_t tadd (time_t t1, long t2);
static void usage (void);
static void writezone (const char * name);
static int yearistype (int year, const char * type);
#if !(HAVE_STRERROR - 0)
static char * strerror P((int));
#endif /* !(HAVE_STRERROR - 0) */
#ifndef HAVE_STRERROR
static char * strerror (int);
#endif
static int charcnt;
static int errors;
@ -271,8 +263,8 @@ struct lookup {
const int l_value;
};
static struct lookup const * byword P((const char * string,
const struct lookup * lp));
static struct lookup const * byword (const char * string,
const struct lookup * lp);
static struct lookup const line_codes[] = {
{ "Rule", LC_RULE },
@ -389,10 +381,8 @@ char * const ptr;
** Error handling.
*/
#if !(HAVE_STRERROR - 0)
static char *
strerror(errnum)
int errnum;
#ifndef HAVE_STRERROR
static char *strerror(int errnum)
{
extern char * sys_errlist[];
extern int sys_nerr;
@ -400,14 +390,9 @@ int errnum;
return (errnum > 0 && errnum <= sys_nerr) ?
sys_errlist[errnum] : _("Unknown system error");
}
#endif /* !(HAVE_STRERROR - 0) */
#endif
static void
eats(name, num, rname, rnum)
const char * const name;
const int num;
const char * const rname;
const int rnum;
static void eats(const char *name, const int num, const char *rname, const int rnum)
{
filename = name;
linenum = num;
@ -415,17 +400,12 @@ const int rnum;
rlinenum = rnum;
}
static void
eat(name, num)
const char * const name;
const int num;
static void eat(const char *name, const int num)
{
eats(name, num, (char *) NULL, -1);
}
static void
error(string)
const char * const string;
static void error(const char *string)
{
/*
** Match the format of "cc" to allow sh users to
@ -441,9 +421,7 @@ const char * const string;
++errors;
}
static void
warning(string)
const char * const string;
static void warning(const char *string)
{
char * cp;
@ -454,8 +432,7 @@ const char * const string;
--errors;
}
static void
usage P((void))
static void usage(void)
{
(void) fprintf(stderr, _("%s: usage is %s [ --version ] [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"),
progname, progname);
@ -469,25 +446,15 @@ static const char * leapsec;
static const char * yitcommand;
static int sflag = FALSE;
int
main(argc, argv)
int argc;
char * argv[];
int main(int argc, char *argv[])
{
register int i;
register int j;
register int c;
#ifdef unix
#ifndef WIN32
(void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
#endif /* defined unix */
#if HAVE_GETTEXT - 0
(void) setlocale(LC_MESSAGES, "");
#ifdef TZ_DOMAINDIR
(void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
#endif /* defined TEXTDOMAINDIR */
(void) textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT - 0 */
#endif /* !WIN32 */
progname = argv[0];
for (i = 1; i < argc; ++i)
if (strcmp(argv[i], "--version") == 0) {
@ -558,7 +525,7 @@ _("%s: More than one -L option specified\n"),
if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
usage(); /* usage message by request */
if (directory == NULL)
directory = TZDIR;
directory = "data";
if (yitcommand == NULL)
yitcommand = "yearistype";
@ -600,10 +567,7 @@ _("%s: More than one -L option specified\n"),
return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
static void
dolink(fromfile, tofile)
const char * const fromfile;
const char * const tofile;
static void dolink(const char *fromfile, const char *tofile)
{
register char * fromname;
register char * toname;
@ -635,7 +599,7 @@ const char * const tofile;
(void) exit(EXIT_FAILURE);
result = link(fromname, toname);
#if (HAVE_SYMLINK - 0)
#ifdef HAVE_SYMLINK
if (result != 0 &&
access(fromname, F_OK) == 0 &&
!itsdir(fromname)) {
@ -682,8 +646,7 @@ warning(_("hard link failed, symbolic link used"));
#define MAX_BITS_IN_FILE 32
#define TIME_T_BITS_IN_FILE ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? TYPE_BIT(time_t) : MAX_BITS_IN_FILE)
static void
setboundaries P((void))
static void setboundaries(void)
{
if (TYPE_SIGNED(time_t)) {
min_time = ~ (time_t) 0;
@ -697,15 +660,13 @@ setboundaries P((void))
max_time <<= TIME_T_BITS_IN_FILE - 1;
--max_time;
}
min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year;
max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year;
min_year = TM_YEAR_BASE + pg_gmtime(&min_time)->tm_year;
max_year = TM_YEAR_BASE + pg_gmtime(&max_time)->tm_year;
min_year_representable = min_year;
max_year_representable = max_year;
}
static int
itsdir(name)
const char * const name;
static int itsdir(const char *name)
{
register char * myname;
register int accres;
@ -725,17 +686,13 @@ const char * const name;
** Sort by rule name.
*/
static int
rcomp(cp1, cp2)
const void * cp1;
const void * cp2;
static int rcomp(const void *cp1, const void *cp2)
{
return strcmp(((const struct rule *) cp1)->r_name,
((const struct rule *) cp2)->r_name);
}
static void
associate P((void))
static void associate(void)
{
register struct zone * zp;
register struct rule * rp;
@ -810,9 +767,7 @@ associate P((void))
(void) exit(EXIT_FAILURE);
}
static void
infile(name)
const char * name;
static void infile(const char *name)
{
register FILE * fp;
register char ** fields;
@ -914,11 +869,7 @@ _("%s: panic: Invalid l_value %d\n"),
** Call error with errstring and return zero on errors.
*/
static long
gethms(string, errstring, signable)
const char * string;
const char * const errstring;
const int signable;
static long gethms(const char *string, const char *errstring, const int signable)
{
int hh, mm, ss, sign;
@ -953,10 +904,7 @@ const int signable;
eitol(SECSPERMIN) + eitol(ss));
}
static void
inrule(fields, nfields)
register char ** const fields;
const int nfields;
static void inrule(register char **fields, const int nfields)
{
static struct rule r;
@ -980,10 +928,7 @@ const int nfields;
rules[nrules++] = r;
}
static int
inzone(fields, nfields)
register char ** const fields;
const int nfields;
static int inzone(register char **fields, const int nfields)
{
register int i;
static char * buf;
@ -1025,10 +970,7 @@ _("duplicate zone name %s (file \"%s\", line %d)"),
return inzsub(fields, nfields, FALSE);
}
static int
inzcont(fields, nfields)
register char ** const fields;
const int nfields;
static int inzcont(register char **fields, const int nfields)
{
if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
error(_("wrong number of fields on Zone continuation line"));
@ -1037,11 +979,7 @@ const int nfields;
return inzsub(fields, nfields, TRUE);
}
static int
inzsub(fields, nfields, iscont)
register char ** const fields;
const int nfields;
const int iscont;
static int inzsub(register char **fields, const int nfields, const int iscont)
{
register char * cp;
static struct zone z;
@ -1114,10 +1052,7 @@ const int iscont;
return hasuntil;
}
static void
inleap(fields, nfields)
register char ** const fields;
const int nfields;
static void inleap(register char **fields, const int nfields)
{
register const char * cp;
register const struct lookup * lp;
@ -1211,10 +1146,7 @@ const int nfields;
}
}
static void
inlink(fields, nfields)
register char ** const fields;
const int nfields;
static void inlink(register char **fields, const int nfields)
{
struct link l;
@ -1239,15 +1171,7 @@ const int nfields;
links[nlinks++] = l;
}
static void
rulesub(rp, loyearp, hiyearp, typep, monthp, dayp, timep)
register struct rule * const rp;
const char * const loyearp;
const char * const hiyearp;
const char * const typep;
const char * const monthp;
const char * const dayp;
const char * const timep;
static void rulesub(register struct rule *rp, const char *loyearp, const char *hiyearp, const char *typep, const char *monthp, const char *dayp, const char *timep)
{
register const struct lookup * lp;
register const char * cp;
@ -1399,10 +1323,7 @@ const char * const timep;
ifree(dp);
}
static void
convert(val, buf)
const long val;
char * const buf;
static void convert(const long val, char *buf)
{
register int i;
register long shift;
@ -1411,10 +1332,7 @@ char * const buf;
buf[i] = val >> shift;
}
static void
puttzcode(val, fp)
const long val;
FILE * const fp;
static void puttzcode(const long val, FILE *fp)
{
char buf[4];
@ -1422,10 +1340,7 @@ FILE * const fp;
(void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
}
static int
atcomp(avp, bvp)
void * avp;
void * bvp;
static int atcomp(const void *avp,const void *bvp)
{
if (((struct attype *) avp)->at < ((struct attype *) bvp)->at)
return -1;
@ -1434,9 +1349,7 @@ void * bvp;
else return 0;
}
static void
writezone(name)
const char * const name;
static void writezone(const char *name)
{
register FILE * fp;
register int i, j;
@ -1579,12 +1492,7 @@ const char * const name;
}
}
static void
doabbr(abbr, format, letters, isdst)
char * const abbr;
const char * const format;
const char * const letters;
const int isdst;
static void doabbr(char *abbr, const char *format, const char *letters, const int isdst)
{
if (strchr(format, '/') == NULL) {
if (letters == NULL)
@ -1598,16 +1506,14 @@ const int isdst;
}
}
static void
outzone(zpfirst, zonecount)
const struct zone * const zpfirst;
const int zonecount;
static void outzone(const struct zone *zpfirst, const int zonecount)
{
register const struct zone * zp;
register struct rule * rp;
register int i, j;
register int usestart, useuntil;
register time_t starttime, untiltime;
register time_t starttime = 0;
register time_t untiltime = 0;
register long gmtoff;
register long stdoff;
register int year;
@ -1617,8 +1523,6 @@ const int zonecount;
register int type;
char startbuf[BUFSIZ];
INITIALIZE(untiltime);
INITIALIZE(starttime);
/*
** Now. . .finally. . .generate some useful data!
*/
@ -1676,11 +1580,10 @@ const int zonecount;
}
for ( ; ; ) {
register int k;
register time_t jtime, ktime;
register time_t jtime, ktime = 0;
register long offset;
char buf[BUFSIZ];
INITIALIZE(ktime);
if (useuntil) {
/*
** Turn untiltime into UTC
@ -1786,10 +1689,7 @@ error(_("can't determine time zone abbreviation to use just after until time"));
writezone(zpfirst->z_name);
}
static void
addtt(starttime, type)
const time_t starttime;
int type;
static void addtt(const time_t starttime, int type)
{
if (starttime <= min_time ||
(timecnt == 1 && attypes[0].at < min_time)) {
@ -1814,13 +1714,7 @@ int type;
++timecnt;
}
static int
addtype(gmtoff, abbr, isdst, ttisstd, ttisgmt)
const long gmtoff;
const char * const abbr;
const int isdst;
const int ttisstd;
const int ttisgmt;
static int addtype(const long gmtoff, const char *abbr, const int isdst, const int ttisstd, const int ttisgmt)
{
register int i, j;
@ -1870,12 +1764,7 @@ const int ttisgmt;
return i;
}
static void
leapadd(t, positive, rolling, count)
const time_t t;
const int positive;
const int rolling;
int count;
static void leapadd(const time_t t, const int positive, const int rolling, int count)
{
register int i, j;
@ -1904,8 +1793,7 @@ int count;
} while (positive && --count != 0);
}
static void
adjleap P((void))
static void adjleap(void)
{
register int i;
register long last = 0;
@ -1919,10 +1807,7 @@ adjleap P((void))
}
}
static int
yearistype(year, type)
const int year;
const char * const type;
static int yearistype(const int year, const char *type)
{
static char * buf;
int result;
@ -1945,18 +1830,13 @@ const char * const type;
(void) exit(EXIT_FAILURE);
}
static int
lowerit(a)
int a;
static int lowerit(int a)
{
a = (unsigned char) a;
return (isascii(a) && isupper(a)) ? tolower(a) : a;
}
static int
ciequal(ap, bp) /* case-insensitive equality */
register const char * ap;
register const char * bp;
static int ciequal(register const char *ap, register const char *bp)
{
while (lowerit(*ap) == lowerit(*bp++))
if (*ap++ == '\0')
@ -1964,10 +1844,7 @@ register const char * bp;
return FALSE;
}
static int
itsabbr(abbr, word)
register const char * abbr;
register const char * word;
static int itsabbr(register const char *abbr, register const char *word)
{
if (lowerit(*abbr) != lowerit(*word))
return FALSE;
@ -1980,10 +1857,7 @@ register const char * word;
return TRUE;
}
static const struct lookup *
byword(word, table)
register const char * const word;
register const struct lookup * const table;
static const struct lookup *byword(register const char *word, register const struct lookup *table)
{
register const struct lookup * foundlp;
register const struct lookup * lp;
@ -2009,9 +1883,7 @@ register const struct lookup * const table;
return foundlp;
}
static char **
getfields(cp)
register char * cp;
static char **getfields(register char *cp)
{
register char * dp;
register char ** array;
@ -2045,10 +1917,7 @@ register char * cp;
return array;
}
static long
oadd(t1, t2)
const long t1;
const long t2;
static long oadd(const long t1, const long t2)
{
register long t;
@ -2060,10 +1929,7 @@ const long t2;
return t;
}
static time_t
tadd(t1, t2)
const time_t t1;
const long t2;
static time_t tadd(const time_t t1, const long t2)
{
register time_t t;
@ -2084,10 +1950,7 @@ const long t2;
** 1970, 00:00 LOCAL time - in that year that the rule refers to.
*/
static time_t
rpytime(rp, wantedy)
register const struct rule * const rp;
register const int wantedy;
static time_t rpytime(register const struct rule *rp, register const int wantedy)
{
register int y, m, i;
register long dayoff; /* with a nod to Margaret O. */
@ -2168,9 +2031,7 @@ register const int wantedy;
return tadd(t, rp->r_tod);
}
static void
newabbr(string)
const char * const string;
static void newabbr(const char *string)
{
register int i;
@ -2183,9 +2044,7 @@ const char * const string;
charcnt += eitol(i);
}
static int
mkdirs(argname)
char * const argname;
static int mkdirs(char *argname)
{
register char * name;
register char * cp;
@ -2195,7 +2054,7 @@ char * const argname;
cp = name = ecpyalloc(argname);
while ((cp = strchr(cp + 1, '/')) != 0) {
*cp = '\0';
#ifndef unix
#ifdef WIN32
/*
** DOS drive specifier?
*/
@ -2204,7 +2063,7 @@ char * const argname;
*cp = '/';
continue;
}
#endif /* !defined unix */
#endif /* WIN32 */
if (!itsdir(name)) {
/*
** It doesn't seem to exist, so we try to create it.
@ -2230,9 +2089,7 @@ _("%s: Can't create directory %s: %s\n"),
return 0;
}
static long
eitol(i)
const int i;
static long eitol(const int i)
{
long l;
@ -2262,3 +2119,13 @@ int link(const char *oldpath, const char *newpath) {
return 0;
}
#endif
/*
* This allows zic to compile by just assigning a dummy value.
* localtime.c references it, but no one uses it from zic.
*/
char *
pg_TZDIR(void)
{
return NULL;
}