Commit 921d749b authored by Tom Lane's avatar Tom Lane

Adjust our timezone library to use pg_time_t (typedef'd as int64) in

place of time_t, as per prior discussion.  The behavior does not change
on machines without a 64-bit-int type, but on machines with one, which
is most, we are rid of the bizarre boundary behavior at the edges of
the 32-bit-time_t range (1901 and 2038).  The system will now treat
times over the full supported timestamp range as being in your local
time zone.  It may seem a little bizarre to consider that times in
4000 BC are PST or EST, but this is surely at least as reasonable as
propagating Gregorian calendar rules back that far.

I did not modify the format of the zic timezone database files, which
means that for the moment the system will not know about daylight-savings
periods outside the range 1901-2038.  Given the way the files are set up,
it's not a simple decision like 'widen to 64 bits'; we have to actually
think about the range of years that need to be supported.  We should
probably inquire what the plans of the upstream zic people are before
making any decisions of our own.
parent 473ac70a
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.167 2004/05/22 23:14:37 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.168 2004/06/03 02:08:00 tgl Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
......@@ -141,6 +141,7 @@
#include "postgres.h"
#include <time.h>
#include <unistd.h>
#include "access/gistscan.h"
......@@ -1858,7 +1859,7 @@ xact_desc(char *buf, uint8 xl_info, char *rec)
if (info == XLOG_XACT_COMMIT)
{
xl_xact_commit *xlrec = (xl_xact_commit *) rec;
struct pg_tm *tm = pg_localtime(&xlrec->xtime);
struct tm *tm = 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,
......@@ -1868,7 +1869,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 pg_tm *tm = pg_localtime(&xlrec->xtime);
struct tm *tm = 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,
......
......@@ -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.145 2004/05/29 22:48:18 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.146 2004/06/03 02:08:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -16,6 +16,7 @@
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
......@@ -2761,9 +2762,9 @@ str_time(time_t tnow)
{
static char buf[128];
pg_strftime(buf, sizeof(buf),
strftime(buf, sizeof(buf),
"%Y-%m-%d %H:%M:%S %Z",
pg_localtime(&tnow));
localtime(&tnow));
return buf;
}
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.68 2004/05/26 04:41:05 neilc Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.69 2004/06/03 02:08:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -38,7 +38,6 @@
#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"
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootscanner.l,v 1.34 2004/05/21 05:07:56 tgl Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootscanner.l,v 1.35 2004/06/03 02:08:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -29,7 +29,6 @@
#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"
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.182 2004/05/29 22:48:18 tgl Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.183 2004/06/03 02:08:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -34,7 +34,6 @@
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "postmaster/bgwriter.h"
#include "pgtime.h"
#include "storage/freespace.h"
#include "storage/ipc.h"
#include "storage/pg_shmem.h"
......
......@@ -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.44 2004/05/21 05:07:57 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_main.c,v 1.45 2004/06/03 02:08:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -31,7 +31,6 @@
#include "optimizer/geqo_mutation.h"
#include "optimizer/geqo_pool.h"
#include "optimizer/geqo_selection.h"
#include "pgtime.h"
/*
......
......@@ -37,13 +37,14 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.2 2004/05/31 03:47:59 tgl Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.3 2004/06/03 02:08:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <signal.h>
#include <time.h>
#include "access/xlog.h"
#include "libpq/pqsignal.h"
......
......@@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2003, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.73 2004/05/29 22:48:19 tgl Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.74 2004/06/03 02:08:03 tgl Exp $
* ----------
*/
#include "postgres.h"
......@@ -29,6 +29,7 @@
#include <arpa/inet.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include "pgstat.h"
......
......@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.401 2004/05/30 03:50:11 tgl Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.402 2004/06/03 02:08:03 tgl Exp $
*
* NOTES
*
......@@ -62,6 +62,7 @@
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/wait.h>
#include <ctype.h>
#include <sys/stat.h>
......@@ -97,7 +98,6 @@
#include "miscadmin.h"
#include "nodes/nodes.h"
#include "postmaster/postmaster.h"
#include "pgtime.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/pg_shmem.h"
......
......@@ -12,12 +12,14 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.43 2004/04/21 18:06:30 tgl Exp $
* $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.44 2004/06/03 02:08:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <time.h>
#include "access/xact.h"
#include "storage/buf_internals.h"
#include "storage/bufmgr.h"
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.417 2004/05/29 22:48:20 tgl Exp $
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.418 2004/06/03 02:08:03 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
......@@ -46,7 +46,6 @@
#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"
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.98 2004/05/31 18:53:17 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.99 2004/06/03 02:08:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -23,7 +23,6 @@
#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"
......@@ -295,14 +294,11 @@ date2timestamptz(DateADT dateVal)
TimestampTz result;
struct pg_tm tt,
*tm = &tt;
int tz;
j2date(dateVal + POSTGRES_EPOCH_JDATE,
&(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
{
int tz;
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
......@@ -314,16 +310,6 @@ date2timestamptz(DateADT dateVal)
#else
result = dateVal * 86400.0 + tz;
#endif
}
else
{
/* Outside of range for timezone support, so assume UTC */
#ifdef HAVE_INT64_TIMESTAMP
result = (dateVal * INT64CONST(86400000000));
#else
result = dateVal * 86400.0;
#endif
}
return result;
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.129 2004/05/31 18:53:17 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.130 2004/06/03 02:08:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -40,9 +40,11 @@ static int DecodeDate(char *str, int fmask, int *tmask, struct pg_tm * tm);
static void TrimTrailingZeros(char *str);
int day_tab[2][13] = {
const int day_tab[2][13] =
{
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}};
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}
};
char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
......@@ -1572,50 +1574,59 @@ DecodeDateTime(char **field, int *ftype, int nf,
* (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
* variety of, ahem, odd behaviors on various platforms. We used to try to
* use mktime() here, but finally gave it up as a bad job. Avoid using
* mktime() anywhere else.
* Note: it might seem that we should use mktime() for this, but bitter
* experience teaches otherwise. In particular, mktime() is generally
* incapable of coping reasonably with "impossible" times within a
* spring-forward DST transition. Typical implementations of mktime()
* turn out to be loops around localtime() anyway, so they're not even
* any faster than this code.
*/
int
DetermineLocalTimeZone(struct pg_tm * tm)
DetermineLocalTimeZone(struct pg_tm *tm)
{
int tz;
if (HasCTZSet)
{
tm->tm_isdst = 0; /* for lack of a better idea */
tz = CTimeZone;
}
else if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
{
/*
* First, generate the time_t value corresponding to the given
* y/m/d/h/m/s taken as GMT time. This will not overflow (at
* least not for time_t taken as signed) because of the range
* check we did above.
*/
long day,
int date,
sec;
pg_time_t day,
mysec,
locsec,
delta1,
delta2;
time_t mytime;
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;
mytime = (time_t) mysec;
if (HasCTZSet)
{
tm->tm_isdst = 0; /* for lack of a better idea */
return CTimeZone;
}
/*
* First, generate the pg_time_t value corresponding to the given
* y/m/d/h/m/s taken as GMT time. If this overflows, punt and
* decide the timezone is GMT. (We only need to worry about overflow
* on machines where pg_time_t is 32 bits.)
*/
if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
goto overflow;
date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - UNIX_EPOCH_JDATE;
day = ((pg_time_t) date) * 86400;
if (day / 86400 != date)
goto overflow;
sec = tm->tm_sec + (tm->tm_min + tm->tm_hour * 60) * 60;
mysec = day + sec;
/* since sec >= 0, overflow could only be from +day to -mysec */
if (mysec < 0 && day > 0)
goto overflow;
/*
* Use localtime to convert that time_t to broken-down time,
* and reassemble to get a representation of local time.
* Use pg_localtime to convert that pg_time_t to broken-down time,
* and reassemble to get a representation of local time. (We could get
* overflow of a few hours in the result, but the delta calculation
* should still work.)
*/
tx = pg_localtime(&mytime);
tx = pg_localtime(&mysec);
if (!tx)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
goto overflow; /* probably can't happen */
day = date2j(tx->tm_year + 1900, tx->tm_mon + 1, tx->tm_mday) -
UNIX_EPOCH_JDATE;
locsec = tx->tm_sec + (tx->tm_min + (day * 24 + tx->tm_hour) * 60) * 60;
......@@ -1625,21 +1636,24 @@ DetermineLocalTimeZone(struct pg_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
* daylight-savings-time transition, then this is not the time
* offset we want. So, adjust the time_t to be what we think
* offset we want. So, adjust the pg_time_t to be what we think
* the GMT time corresponding to our target local time is, and
* repeat the localtime() call and delta calculation.
* repeat the pg_localtime() call and delta calculation.
*
* We have to watch out for overflow while adjusting the pg_time_t.
*/
if ((delta1 < 0) ? (mysec < 0 && (mysec + delta1) > 0) :
(mysec > 0 && (mysec + delta1) < 0))
goto overflow;
mysec += delta1;
mytime = (time_t) mysec;
tx = pg_localtime(&mytime);
tx = pg_localtime(&mysec);
if (!tx)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
goto overflow; /* probably can't happen */
day = date2j(tx->tm_year + 1900, tx->tm_mon + 1, tx->tm_mday) -
UNIX_EPOCH_JDATE;
locsec = tx->tm_sec + (tx->tm_min + (day * 24 + tx->tm_hour) * 60) * 60;
......@@ -1658,13 +1672,14 @@ DetermineLocalTimeZone(struct pg_tm * tm)
*/
if (delta2 != delta1 && tx->tm_isdst != 0)
{
mysec += (delta2 - delta1);
mytime = (time_t) mysec;
tx = pg_localtime(&mytime);
delta2 -= delta1;
if ((delta2 < 0) ? (mysec < 0 && (mysec + delta2) > 0) :
(mysec > 0 && (mysec + delta2) < 0))
goto overflow;
mysec += delta2;
tx = pg_localtime(&mysec);
if (!tx)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
goto overflow; /* probably can't happen */
day = date2j(tx->tm_year + 1900, tx->tm_mon + 1, tx->tm_mday) -
UNIX_EPOCH_JDATE;
locsec = tx->tm_sec + (tx->tm_min + (day * 24 + tx->tm_hour) * 60) * 60;
......@@ -1672,15 +1687,13 @@ DetermineLocalTimeZone(struct pg_tm * tm)
}
tm->tm_isdst = tx->tm_isdst;
tz = (int) delta2;
}
else
{
/* Given date is out of range, so assume UTC */
tm->tm_isdst = 0;
tz = 0;
}
return tz;
overflow:
/* Given date is out of range, so assume UTC */
tm->tm_isdst = 0;
return 0;
}
......
......@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.122 2004/05/21 16:08:47 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.123 2004/06/03 02:08:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -19,6 +19,7 @@
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <sys/time.h>
#include "access/xact.h"
......@@ -179,7 +180,7 @@ GetCurrentTimeUsec(struct pg_tm * tm, fsec_t *fsec, int *tzp)
void
abstime2tm(AbsoluteTime _time, int *tzp, struct pg_tm * tm, char **tzn)
{
time_t time = (time_t) _time;
pg_time_t time = (pg_time_t) _time;
struct pg_tm *tx;
/*
......@@ -1667,10 +1668,10 @@ timeofday(PG_FUNCTION_ARGS)
char buf[128];
text *result;
int len;
time_t tt;
pg_time_t tt;
gettimeofday(&tp, &tpz);
tt = (time_t) tp.tv_sec;
tt = (pg_time_t) tp.tv_sec;
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);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.107 2004/05/31 18:31:51 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.108 2004/06/03 02:08:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -921,16 +921,14 @@ dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
} /* dt2time() */
/* timestamp2tm()
* Convert timestamp data type to POSIX time structure.
/*
* timestamp2tm() - Convert timestamp data type to POSIX time structure.
*
* Note that year is _not_ 1900-based, but is an explicit full value.
* Also, month is one-based, _not_ zero-based.
* Returns:
* 0 on success
* -1 on out of range
*
* For dates within the system-supported time_t range, convert to the
* local time zone. If out of this range, leave as GMT. - tgl 97/05/27
*/
int
timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
......@@ -942,8 +940,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
double date;
double time;
#endif
time_t utime;
struct pg_tm *tx;
pg_time_t utime;
/*
* If HasCTZSet is true then we have a brute force time zone
......@@ -988,8 +985,17 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
if (tzp != NULL)
/* Done if no TZ conversion wanted */
if (tzp == NULL)
{
tm->tm_isdst = -1;
tm->tm_gmtoff = 0;
tm->tm_zone = NULL;
if (tzn != NULL)
*tzn = NULL;
return 0;
}
/*
* We have a brute force time zone per SQL99? Then use it without
* change since we have already rotated to the time zone.
......@@ -1002,30 +1008,31 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
tm->tm_zone = NULL;
if (tzn != NULL)
*tzn = NULL;
return 0;
}
/*
* Does this fall within the capabilities of the localtime()
* interface? Then use this to rotate to the local time zone.
*/
else if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
{
/*
* Convert to integer, avoiding platform-specific
* roundoff-in-wrong-direction errors, and adjust to
* Unix epoch. Note we have to do this in one step
* because the intermediate result before adjustment
* won't necessarily fit in an int32.
* If the time falls within the range of pg_time_t, use pg_localtime()
* to rotate to the local time zone.
*
* First, convert to an integral timestamp, avoiding possibly
* platform-specific roundoff-in-wrong-direction errors, and adjust to
* Unix epoch. Then see if we can convert to pg_time_t without loss.
* This coding avoids hardwiring any assumptions about the width of
* pg_time_t, so it should behave sanely on machines without int64.
*/
#ifdef HAVE_INT64_TIMESTAMP
utime = (dt - *fsec) / INT64CONST(1000000) +
dt = (dt - *fsec) / INT64CONST(1000000) +
(POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * 86400;
#else
utime = rint(dt - *fsec +
dt = rint(dt - *fsec +
(POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * 86400);
#endif
utime = (pg_time_t) dt;
if ((Timestamp) utime == dt)
{
struct pg_tm *tx = pg_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;
......@@ -1035,23 +1042,20 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
tm->tm_isdst = tx->tm_isdst;
tm->tm_gmtoff = tx->tm_gmtoff;
tm->tm_zone = tx->tm_zone;
*tzp = -(tm->tm_gmtoff);
if (tzn != NULL)
*tzn = (char *) tm->tm_zone;
}
else
{
/*
* When out of range of pg_time_t, treat as GMT
*/
*tzp = 0;
/* Mark this as *no* time zone available */
tm->tm_isdst = -1;
if (tzn != NULL)
*tzn = NULL;
}
}
else
{
tm->tm_isdst = -1;
tm->tm_gmtoff = 0;
tm->tm_zone = NULL;
if (tzn != NULL)
*tzn = NULL;
}
......@@ -1224,7 +1228,7 @@ void
GetEpochTime(struct pg_tm * tm)
{
struct pg_tm *t0;
time_t epoch = 0;
pg_time_t epoch = 0;
t0 = pg_gmtime(&epoch);
......@@ -1235,12 +1239,9 @@ GetEpochTime(struct pg_tm * tm)
tm->tm_min = t0->tm_min;
tm->tm_sec = t0->tm_sec;
if (tm->tm_year < 1900)
tm->tm_year += 1900;
tm->tm_mon++;
return;
} /* GetEpochTime() */
}
Timestamp
SetEpochTimestamp(void)
......
......@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.139 2004/05/29 22:48:21 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.140 2004/06/03 02:08:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -45,6 +45,7 @@
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <ctype.h>
......@@ -56,7 +57,6 @@
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "pgtime.h"
#include "postmaster/postmaster.h"
#include "storage/ipc.h"
#include "tcop/tcopprot.h"
......@@ -1217,8 +1217,9 @@ log_line_prefix(StringInfo buf)
time_t stamp_time = time(NULL);
char strfbuf[128];
pg_strftime(strfbuf, sizeof(strfbuf), "%Y-%m-%d %H:%M:%S %Z",
pg_localtime(&stamp_time));
strftime(strfbuf, sizeof(strfbuf),
"%Y-%m-%d %H:%M:%S %Z",
localtime(&stamp_time));
appendStringInfoString(buf, strfbuf);
}
break;
......@@ -1228,8 +1229,9 @@ log_line_prefix(StringInfo buf)
time_t stamp_time = MyProcPort->session_start.tv_sec;
char strfbuf[128];
pg_strftime(strfbuf, sizeof(strfbuf), "%Y-%m-%d %H:%M:%S %Z",
pg_localtime(&stamp_time));
strftime(strfbuf, sizeof(strfbuf),
"%Y-%m-%d %H:%M:%S %Z",
localtime(&stamp_time));
appendStringInfoString(buf, strfbuf);
}
break;
......
......@@ -8,15 +8,16 @@
* 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.14 2004/05/21 05:08:04 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.15 2004/06/03 02:08:05 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"
......
......@@ -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/commands/vacuum.h,v 1.53 2004/05/21 16:22:38 tgl Exp $
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.54 2004/06/03 02:08:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -27,7 +27,6 @@
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "nodes/parsenodes.h"
#include "pgtime.h"
#include "utils/rel.h"
......
......@@ -6,50 +6,29 @@
* 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 $
* $PostgreSQL: pgsql/src/include/pgtime.h,v 1.2 2004/06/03 02:08:06 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"
* The API of this library is generally similar to the corresponding
* C library functions, except that we use pg_time_t which (we hope) is
* 64 bits wide, and which is most definitely signed not unsigned.
*/
#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>
typedef int64 pg_time_t;
/*
* 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_mon; /* origin 0, not 1 */
int tm_year; /* relative to 1900 */
int tm_wday;
int tm_yday;
int tm_isdst;
......@@ -57,9 +36,8 @@ struct pg_tm {
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 struct pg_tm *pg_localtime(const pg_time_t *);
extern struct pg_tm *pg_gmtime(const pg_time_t *);
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);
......@@ -68,6 +46,4 @@ 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 */
......@@ -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.48 2004/05/21 05:08:05 tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.49 2004/06/03 02:08:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -19,7 +19,6 @@
#include <limits.h>
#include <math.h>
#include "pgtime.h"
#include "utils/timestamp.h"
......@@ -232,10 +231,11 @@ do { \
* Include check for leap year.
*/
extern int day_tab[2][13];
extern const int day_tab[2][13];
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
/* Julian date support for date2j() and j2date()
*
* IS_VALID_JULIAN checks the minimum date exactly, but is a bit sloppy
......@@ -257,24 +257,6 @@ extern int day_tab[2][13];
#define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */
#define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */
/*
* Info about limits of the Unix time_t data type. We assume that time_t
* is a signed int32 with origin 1970-01-01. Note this is only relevant
* when we use the C library's time routines for timezone processing.
*/
#define UTIME_MINYEAR (1901)
#define UTIME_MINMONTH (12)
#define UTIME_MINDAY (14)
#define UTIME_MAXYEAR (2038)
#define UTIME_MAXMONTH (01)
#define UTIME_MAXDAY (18)
#define IS_VALID_UTIME(y,m,d) ((((y) > UTIME_MINYEAR) \
|| (((y) == UTIME_MINYEAR) && (((m) > UTIME_MINMONTH) \
|| (((m) == UTIME_MINMONTH) && ((d) >= UTIME_MINDAY))))) \
&& (((y) < UTIME_MAXYEAR) \
|| (((y) == UTIME_MAXYEAR) && (((m) < UTIME_MAXMONTH) \
|| (((m) == UTIME_MAXMONTH) && ((d) <= UTIME_MAXDAY))))))
/*
* Datetime input parsing routines (ParseDateTime, DecodeDateTime, etc)
......
......@@ -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.42 2004/05/21 05:08:05 tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/nabstime.h,v 1.43 2004/06/03 02:08:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -17,7 +17,6 @@
#include <limits.h>
#include "fmgr.h"
#include "pgtime.h"
#include "utils/timestamp.h"
#include "utils/datetime.h"
......@@ -28,9 +27,10 @@
*
* ----------------------------------------------------------------
*/
/*
* Although time_t generally is a long int on 64 bit systems, these two
* types must be 4 bytes, because that's what the system assumes. They
* types must be 4 bytes, because that's what pg_type.h assumes. They
* should be yanked (long) before 2038 and be replaced by timestamp and
* interval.
*/
......
......@@ -672,15 +672,15 @@ SELECT '' AS "64", d1 + interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL;
| Sat Feb 14 17:32:01 1998 PST
| Sun Feb 15 17:32:01 1998 PST
| Mon Feb 16 17:32:01 1998 PST
| Thu Feb 16 17:32:01 0096 BC
| Sun Feb 16 17:32:01 0098
| Fri Feb 16 17:32:01 0598
| Wed Feb 16 17:32:01 1098
| Sun Feb 16 17:32:01 1698
| Fri Feb 16 17:32:01 1798
| Wed Feb 16 17:32:01 1898
| Thu Feb 16 17:32:01 0096 BC PST
| Sun Feb 16 17:32:01 0098 PST
| Fri Feb 16 17:32:01 0598 PST
| Wed Feb 16 17:32:01 1098 PST
| Sun Feb 16 17:32:01 1698 PST
| Fri Feb 16 17:32:01 1798 PST
| Wed Feb 16 17:32:01 1898 PST
| Mon Feb 16 17:32:01 1998 PST
| Sun Feb 16 17:32:01 2098
| Sun Feb 16 17:32:01 2098 PST
| Fri Feb 28 17:32:01 1997 PST
| Fri Feb 28 17:32:01 1997 PST
| Sat Mar 01 17:32:01 1997 PST
......@@ -741,15 +741,15 @@ SELECT '' AS "64", d1 - interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL;
| Wed Feb 14 17:32:01 1996 PST
| Thu Feb 15 17:32:01 1996 PST
| Fri Feb 16 17:32:01 1996 PST
| Mon Feb 16 17:32:01 0098 BC
| Thu Feb 16 17:32:01 0096
| Tue Feb 16 17:32:01 0596
| Sun Feb 16 17:32:01 1096
| Thu Feb 16 17:32:01 1696
| Tue Feb 16 17:32:01 1796
| Sun Feb 16 17:32:01 1896
| Mon Feb 16 17:32:01 0098 BC PST
| Thu Feb 16 17:32:01 0096 PST
| Tue Feb 16 17:32:01 0596 PST
| Sun Feb 16 17:32:01 1096 PST
| Thu Feb 16 17:32:01 1696 PST
| Tue Feb 16 17:32:01 1796 PST
| Sun Feb 16 17:32:01 1896 PST
| Fri Feb 16 17:32:01 1996 PST
| Thu Feb 16 17:32:01 2096
| Thu Feb 16 17:32:01 2096 PST
| Tue Feb 28 17:32:01 1995 PST
| Tue Feb 28 17:32:01 1995 PST
| Wed Mar 01 17:32:01 1995 PST
......
......@@ -1328,14 +1328,14 @@ SELECT '' AS to_char_9, to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. H
-- TO_TIMESTAMP()
SELECT '' AS to_timestamp_1, to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS');
to_timestamp_1 | to_timestamp
----------------+--------------------------
| Sat Feb 16 08:14:30 0097
----------------+------------------------------
| Sat Feb 16 08:14:30 0097 PST
(1 row)
SELECT '' AS to_timestamp_2, to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS');
to_timestamp_2 | to_timestamp
----------------+--------------------------
| Sat Feb 16 08:14:30 0097
----------------+------------------------------
| Sat Feb 16 08:14:30 0097 PST
(1 row)
SELECT '' AS to_timestamp_3, to_timestamp('1985 January 12', 'YYYY FMMonth DD');
......@@ -1353,8 +1353,8 @@ SELECT '' AS to_timestamp_4, to_timestamp('My birthday-> Year: 1976, Month: May,
SELECT '' AS to_timestamp_5, to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD');
to_timestamp_5 | to_timestamp
----------------+--------------------------
| Sat Aug 21 00:00:00 1582
----------------+------------------------------
| Sat Aug 21 00:00:00 1582 PST
(1 row)
SELECT '' AS to_timestamp_6, to_timestamp('15 "text between quote marks" 98 54 45',
......@@ -1387,8 +1387,8 @@ SELECT '' AS to_timestamp_10, to_timestamp('19971116', 'YYYYMMDD');
SELECT '' AS to_timestamp_11, to_timestamp('20000-1116', 'YYYY-MMDD');
to_timestamp_11 | to_timestamp
-----------------+---------------------------
| Thu Nov 16 00:00:00 20000
-----------------+-------------------------------
| Thu Nov 16 00:00:00 20000 PST
(1 row)
SELECT '' AS to_timestamp_12, to_timestamp('9-1116', 'Y-MMDD');
......
......@@ -180,15 +180,15 @@ SELECT '' AS "64", d1 FROM TIMESTAMPTZ_TBL;
| Fri Feb 14 17:32:01 1997 PST
| Sat Feb 15 17:32:01 1997 PST
| Sun Feb 16 17:32:01 1997 PST
| Tue Feb 16 17:32:01 0097 BC
| Sat Feb 16 17:32:01 0097
| Thu Feb 16 17:32:01 0597
| Tue Feb 16 17:32:01 1097
| Sat Feb 16 17:32:01 1697
| Thu Feb 16 17:32:01 1797
| Tue Feb 16 17:32:01 1897
| Tue Feb 16 17:32:01 0097 BC PST
| Sat Feb 16 17:32:01 0097 PST
| Thu Feb 16 17:32:01 0597 PST
| Tue Feb 16 17:32:01 1097 PST
| Sat Feb 16 17:32:01 1697 PST
| Thu Feb 16 17:32:01 1797 PST
| Tue Feb 16 17:32:01 1897 PST
| Sun Feb 16 17:32:01 1997 PST
| Sat Feb 16 17:32:01 2097
| Sat Feb 16 17:32:01 2097 PST
| Wed Feb 28 17:32:01 1996 PST
| Thu Feb 29 17:32:01 1996 PST
| Fri Mar 01 17:32:01 1996 PST
......@@ -249,7 +249,7 @@ SELECT '' AS "48", d1 FROM TIMESTAMPTZ_TBL
| Sat Feb 15 17:32:01 1997 PST
| Sun Feb 16 17:32:01 1997 PST
| Sun Feb 16 17:32:01 1997 PST
| Sat Feb 16 17:32:01 2097
| Sat Feb 16 17:32:01 2097 PST
| Fri Feb 28 17:32:01 1997 PST
| Sat Mar 01 17:32:01 1997 PST
| Tue Dec 30 17:32:01 1997 PST
......@@ -263,16 +263,16 @@ SELECT '' AS "48", d1 FROM TIMESTAMPTZ_TBL
SELECT '' AS "15", d1 FROM TIMESTAMPTZ_TBL
WHERE d1 < timestamp with time zone '1997-01-02';
15 | d1
----+------------------------------
----+---------------------------------
| -infinity
| Wed Dec 31 16:00:00 1969 PST
| Tue Feb 16 17:32:01 0097 BC
| Sat Feb 16 17:32:01 0097
| Thu Feb 16 17:32:01 0597
| Tue Feb 16 17:32:01 1097
| Sat Feb 16 17:32:01 1697
| Thu Feb 16 17:32:01 1797
| Tue Feb 16 17:32:01 1897
| Tue Feb 16 17:32:01 0097 BC PST
| Sat Feb 16 17:32:01 0097 PST
| Thu Feb 16 17:32:01 0597 PST
| Tue Feb 16 17:32:01 1097 PST
| Sat Feb 16 17:32:01 1697 PST
| Thu Feb 16 17:32:01 1797 PST
| Tue Feb 16 17:32:01 1897 PST
| Wed Feb 28 17:32:01 1996 PST
| Thu Feb 29 17:32:01 1996 PST
| Fri Mar 01 17:32:01 1996 PST
......@@ -332,15 +332,15 @@ SELECT '' AS "63", d1 FROM TIMESTAMPTZ_TBL
| Fri Feb 14 17:32:01 1997 PST
| Sat Feb 15 17:32:01 1997 PST
| Sun Feb 16 17:32:01 1997 PST
| Tue Feb 16 17:32:01 0097 BC
| Sat Feb 16 17:32:01 0097
| Thu Feb 16 17:32:01 0597
| Tue Feb 16 17:32:01 1097
| Sat Feb 16 17:32:01 1697
| Thu Feb 16 17:32:01 1797
| Tue Feb 16 17:32:01 1897
| Tue Feb 16 17:32:01 0097 BC PST
| Sat Feb 16 17:32:01 0097 PST
| Thu Feb 16 17:32:01 0597 PST
| Tue Feb 16 17:32:01 1097 PST
| Sat Feb 16 17:32:01 1697 PST
| Thu Feb 16 17:32:01 1797 PST
| Tue Feb 16 17:32:01 1897 PST
| Sun Feb 16 17:32:01 1997 PST
| Sat Feb 16 17:32:01 2097
| Sat Feb 16 17:32:01 2097 PST
| Wed Feb 28 17:32:01 1996 PST
| Thu Feb 29 17:32:01 1996 PST
| Fri Mar 01 17:32:01 1996 PST
......@@ -360,17 +360,17 @@ SELECT '' AS "63", d1 FROM TIMESTAMPTZ_TBL
SELECT '' AS "16", d1 FROM TIMESTAMPTZ_TBL
WHERE d1 <= timestamp with time zone '1997-01-02';
16 | d1
----+------------------------------
----+---------------------------------
| -infinity
| Wed Dec 31 16:00:00 1969 PST
| Thu Jan 02 00:00:00 1997 PST
| Tue Feb 16 17:32:01 0097 BC
| Sat Feb 16 17:32:01 0097
| Thu Feb 16 17:32:01 0597
| Tue Feb 16 17:32:01 1097
| Sat Feb 16 17:32:01 1697
| Thu Feb 16 17:32:01 1797
| Tue Feb 16 17:32:01 1897
| Tue Feb 16 17:32:01 0097 BC PST
| Sat Feb 16 17:32:01 0097 PST
| Thu Feb 16 17:32:01 0597 PST
| Tue Feb 16 17:32:01 1097 PST
| Sat Feb 16 17:32:01 1697 PST
| Thu Feb 16 17:32:01 1797 PST
| Tue Feb 16 17:32:01 1897 PST
| Wed Feb 28 17:32:01 1996 PST
| Thu Feb 29 17:32:01 1996 PST
| Fri Mar 01 17:32:01 1996 PST
......@@ -423,7 +423,7 @@ SELECT '' AS "49", d1 FROM TIMESTAMPTZ_TBL
| Sat Feb 15 17:32:01 1997 PST
| Sun Feb 16 17:32:01 1997 PST
| Sun Feb 16 17:32:01 1997 PST
| Sat Feb 16 17:32:01 2097
| Sat Feb 16 17:32:01 2097 PST
| Fri Feb 28 17:32:01 1997 PST
| Sat Mar 01 17:32:01 1997 PST
| Tue Dec 30 17:32:01 1997 PST
......@@ -1396,15 +1396,15 @@ SELECT '' AS to_char_10, to_char(d1, 'YYYY WW IYYY IYY IY I IW')
-- TO_TIMESTAMP()
SELECT '' AS to_timestamp_1, to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS');
to_timestamp_1 | to_timestamp
----------------+--------------------------
| Sat Feb 16 08:14:30 0097
----------------+------------------------------
| Sat Feb 16 08:14:30 0097 PST
(1 row)
SELECT '' AS to_timestamp_2, to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS');
to_timestamp_2 | to_timestamp
----------------+--------------------------
| Sat Feb 16 08:14:30 0097
----------------+------------------------------
| Sat Feb 16 08:14:30 0097 PST
(1 row)
SELECT '' AS to_timestamp_3, to_timestamp('1985 January 12', 'YYYY FMMonth DD');
......@@ -1422,8 +1422,8 @@ SELECT '' AS to_timestamp_4, to_timestamp('My birthday-> Year: 1976, Month: May,
SELECT '' AS to_timestamp_5, to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD');
to_timestamp_5 | to_timestamp
----------------+--------------------------
| Sat Aug 21 00:00:00 1582
----------------+------------------------------
| Sat Aug 21 00:00:00 1582 PST
(1 row)
SELECT '' AS to_timestamp_6, to_timestamp('15 "text between quote marks" 98 54 45',
......@@ -1456,8 +1456,8 @@ SELECT '' AS to_timestamp_10, to_timestamp('19971116', 'YYYYMMDD');
SELECT '' AS to_timestamp_11, to_timestamp('20000-1116', 'YYYY-MMDD');
to_timestamp_11 | to_timestamp
-----------------+---------------------------
| Thu Nov 16 00:00:00 20000
-----------------+-------------------------------
| Thu Nov 16 00:00:00 20000 PST
(1 row)
SELECT '' AS to_timestamp_12, to_timestamp('9-1116', 'Y-MMDD');
......
This diff is collapsed.
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.16 2004/05/25 19:46:21 tgl Exp $
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.17 2004/06/03 02:08:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -16,12 +16,14 @@
#include <ctype.h>
#include <sys/stat.h>
#include <time.h>
#include "miscadmin.h"
#include "pgtime.h"
#include "pgtz.h"
#include "storage/fd.h"
#include "tzfile.h"
#include "utils/datetime.h"
#include "utils/elog.h"
#include "utils/guc.h"
......@@ -107,7 +109,7 @@ win32_get_timezone_abbrev(const char *tz)
#endif
/*
* Convenience subroutine to convert y/m/d to time_t
* Convenience subroutine to convert y/m/d to time_t (NOT pg_time_t)
*/
static time_t
build_time_t(int year, int month, int day)
......@@ -148,6 +150,7 @@ static bool
try_timezone(const char *tzname, struct tztry *tt)
{
int i;
pg_time_t pgtt;
struct tm *systm;
struct pg_tm *pgtm;
char cbuf[TZ_STRLEN_MAX + 1];
......@@ -158,14 +161,15 @@ try_timezone(const char *tzname, struct tztry *tt)
/* Check for match at all the test times */
for (i = 0; i < tt->n_test_times; i++)
{
pgtm = pg_localtime(&(tt->test_times[i]));
pgtt = (pg_time_t) (tt->test_times[i]);
pgtm = pg_localtime(&pgtt);
if (!pgtm)
return false; /* probably shouldn't happen */
systm = localtime(&(tt->test_times[i]));
if (!compare_tm(systm, pgtm))
{
elog(DEBUG4, "Reject TZ \"%s\": at %lu %04d-%02d-%02d %02d:%02d:%02d %s versus %04d-%02d-%02d %02d:%02d:%02d %s",
tzname, (unsigned long) tt->test_times[i],
elog(DEBUG4, "Reject TZ \"%s\": at %ld %04d-%02d-%02d %02d:%02d:%02d %s versus %04d-%02d-%02d %02d:%02d:%02d %s",
tzname, (long) pgtt,
pgtm->tm_year + 1900, pgtm->tm_mon + 1, pgtm->tm_mday,
pgtm->tm_hour, pgtm->tm_min, pgtm->tm_sec,
pgtm->tm_isdst ? "dst" : "std",
......@@ -183,8 +187,8 @@ try_timezone(const char *tzname, struct tztry *tt)
strftime(cbuf, sizeof(cbuf) - 1, "%Z", systm); /* zone abbr */
if (strcmp(TZABBREV(cbuf), pgtm->tm_zone) != 0)
{
elog(DEBUG4, "Reject TZ \"%s\": at %lu \"%s\" versus \"%s\"",
tzname, (unsigned long) tt->test_times[i],
elog(DEBUG4, "Reject TZ \"%s\": at %ld \"%s\" versus \"%s\"",
tzname, (long) pgtt,
pgtm->tm_zone, cbuf);
return false;
}
......@@ -470,21 +474,17 @@ scan_available_timezones(char *tzdir, char *tzdirsub, struct tztry *tt)
bool
tz_acceptable(void)
{
struct pg_tm tt;
time_t time2000;
struct pg_tm *tt;
pg_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.
* To detect leap-second timekeeping, run pg_localtime for what should
* be GMT midnight, 2000-01-01. Insist that the tm_sec value be zero;
* any other result 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)
time2000 = (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * 86400;
tt = pg_localtime(&time2000);
if (tt->tm_sec != 0)
return false;
return true;
......
......@@ -15,7 +15,7 @@
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/strftime.c,v 1.3 2004/05/21 20:59:10 tgl Exp $
* $PostgreSQL: pgsql/src/timezone/strftime.c,v 1.4 2004/06/03 02:08:07 tgl Exp $
*/
#include "postgres.h"
......@@ -265,21 +265,6 @@ _fmt(const char *format, const struct pg_tm * t, char *pt, const char *ptlim,
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;
......
......@@ -3,12 +3,13 @@
* 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/zic.c,v 1.7 2004/05/21 20:59:10 tgl Exp $
* $PostgreSQL: pgsql/src/timezone/zic.c,v 1.8 2004/06/03 02:08:07 tgl Exp $
*/
#include "postgres.h"
#include <locale.h>
#include <limits.h>
#include "pgtz.h"
#include "private.h"
......@@ -71,7 +72,7 @@ struct rule
const char *r_abbrvar; /* variable part of abbreviation */
int r_todo; /* a rule to do (used in outzone) */
time_t r_temp; /* used in outzone */
pg_time_t r_temp; /* used in outzone */
};
/*
......@@ -98,14 +99,14 @@ struct zone
int z_nrules;
struct rule z_untilrule;
time_t z_untiltime;
pg_time_t z_untiltime;
};
extern int link(const char *fromname, const char *toname);
static void addtt(time_t starttime, int type);
static void addtt(pg_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 leapadd(pg_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);
......@@ -138,13 +139,13 @@ 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 pg_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(void);
static time_t tadd(time_t t1, long t2);
static pg_time_t tadd(pg_time_t t1, long t2);
static void usage(void);
static void writezone(const char *name);
static int yearistype(int year, const char *type);
......@@ -158,10 +159,10 @@ static int errors;
static const char *filename;
static int leapcnt;
static int linenum;
static time_t max_time;
static pg_time_t max_time;
static int max_year;
static int max_year_representable;
static time_t min_time;
static pg_time_t min_time;
static int min_year;
static int min_year_representable;
static int noise;
......@@ -354,7 +355,7 @@ static const int len_years[2] = {
static struct attype
{
time_t at;
pg_time_t at;
unsigned char type;
} attypes[TZ_MAX_TIMES];
static long gmtoffs[TZ_MAX_TYPES];
......@@ -363,7 +364,7 @@ static unsigned char abbrinds[TZ_MAX_TYPES];
static char ttisstds[TZ_MAX_TYPES];
static char ttisgmts[TZ_MAX_TYPES];
static char chars[TZ_MAX_CHARS];
static time_t trans[TZ_MAX_LEAPS];
static pg_time_t trans[TZ_MAX_LEAPS];
static long corr[TZ_MAX_LEAPS];
static char roll[TZ_MAX_LEAPS];
......@@ -684,27 +685,26 @@ dolink(const char *fromfile, const char *tofile)
* change to the tz file format.
*/
#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)
#define TIME_T_BITS_IN_FILE 32
static void
setboundaries(void)
{
if (TYPE_SIGNED(time_t))
{
min_time = ~(time_t) 0;
min_time <<= TIME_T_BITS_IN_FILE - 1;
max_time = ~(time_t) 0 - min_time;
if (sflag)
min_time = 0;
}
else
{
min_time = 0;
max_time = 2 - sflag;
max_time <<= TIME_T_BITS_IN_FILE - 1;
--max_time;
}
/*
* pg_time_t is always signed, but might be only 32 bits ...
*/
min_time = ~(pg_time_t) 0;
min_time <<= TYPE_BIT(pg_time_t) - 1;
max_time = ~(pg_time_t) 0 - min_time;
/*
* For the moment, hard-wire the range as 1901 to 2038. We cannot
* go wider without adopting an incompatible zone file format, which
* is a step I'd just as soon not take just yet.
*/
min_time = Max(min_time, (pg_time_t) INT_MIN);
max_time = Min(max_time, (pg_time_t) INT_MAX);
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;
......@@ -1170,7 +1170,7 @@ inleap(register char **fields, const int nfields)
day;
long dayoff,
tod;
time_t t;
pg_time_t t;
if (nfields != LEAP_FIELDS)
{
......@@ -1223,11 +1223,6 @@ inleap(register char **fields, const int nfields)
return;
}
dayoff = oadd(dayoff, eitol(day - 1));
if (dayoff < 0 && !TYPE_SIGNED(time_t))
{
error(_("time before zero"));
return;
}
if (dayoff < min_time / SECSPERDAY)
{
error(_("time too small"));
......@@ -1238,7 +1233,7 @@ inleap(register char **fields, const int nfields)
error(_("time too large"));
return;
}
t = (time_t) dayoff *SECSPERDAY;
t = (pg_time_t) dayoff *SECSPERDAY;
tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE);
cp = fields[LP_CORR];
......@@ -1525,7 +1520,7 @@ writezone(const char *name)
j;
static char *fullname;
static struct tzhead tzh;
time_t ats[TZ_MAX_TIMES];
pg_time_t ats[TZ_MAX_TIMES];
unsigned char types[TZ_MAX_TIMES];
/*
......@@ -1711,8 +1706,8 @@ outzone(const struct zone * zpfirst, const int zonecount)
j;
register int usestart,
useuntil;
register time_t starttime = 0;
register time_t untiltime = 0;
register pg_time_t starttime = 0;
register pg_time_t untiltime = 0;
register long gmtoff;
register long stdoff;
register int year;
......@@ -1790,7 +1785,7 @@ outzone(const struct zone * zpfirst, const int zonecount)
for (;;)
{
register int k;
register time_t jtime,
register pg_time_t jtime,
ktime = 0;
register long offset;
char buf[BUFSIZ];
......@@ -1911,7 +1906,7 @@ outzone(const struct zone * zpfirst, const int zonecount)
}
static void
addtt(const time_t starttime, int type)
addtt(const pg_time_t starttime, int type)
{
if (starttime <= min_time ||
(timecnt == 1 && attypes[0].at < min_time))
......@@ -1999,7 +1994,7 @@ addtype(const long gmtoff, const char *abbr, const int isdst,
}
static void
leapadd(const time_t t, const int positive, const int rolling, int count)
leapadd(const pg_time_t t, const int positive, const int rolling, int count)
{
register int i,
j;
......@@ -2191,10 +2186,10 @@ oadd(const long t1, const long t2)
return t;
}
static time_t
tadd(const time_t t1, const long t2)
static pg_time_t
tadd(const pg_time_t t1, const long t2)
{
register time_t t;
register pg_time_t t;
if (t1 == max_time && t2 > 0)
return max_time;
......@@ -2214,14 +2209,14 @@ tadd(const time_t t1, const long t2)
* 1970, 00:00 LOCAL time - in that year that the rule refers to.
*/
static time_t
static pg_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. */
register time_t t;
register pg_time_t t;
if (wantedy == INT_MIN)
return min_time;
......@@ -2302,13 +2297,11 @@ rpytime(register const struct rule * rp, register const int wantedy)
(void) exit(EXIT_FAILURE);
}
}
if (dayoff < 0 && !TYPE_SIGNED(time_t))
return min_time;
if (dayoff < min_time / SECSPERDAY)
return min_time;
if (dayoff > max_time / SECSPERDAY)
return max_time;
t = (time_t) dayoff *SECSPERDAY;
t = (pg_time_t) dayoff *SECSPERDAY;
return tadd(t, rp->r_tod);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment