Commit d685417f authored by Tom Lane's avatar Tom Lane

Avoid repeated computation of the constants date2j(1970, 1, 1) and

date2j(2000, 1, 1).  Should make for some marginal speed improvement
in date/time operations.
parent 3b4ca4c0
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.79 2003/02/13 17:04:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.80 2003/04/04 04:50:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -91,7 +91,7 @@ date_in(PG_FUNCTION_ARGS)
elog(ERROR, "Unrecognized date external representation '%s'", str);
}
date = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1));
date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
PG_RETURN_DATEADT(date);
}
......@@ -108,7 +108,7 @@ date_out(PG_FUNCTION_ARGS)
*tm = &tt;
char buf[MAXDATELEN + 1];
j2date((date + date2j(2000, 1, 1)),
j2date(date + POSTGRES_EPOCH_JDATE,
&(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
EncodeDateOnly(tm, DateStyle, buf);
......@@ -256,9 +256,10 @@ date_pl_interval(PG_FUNCTION_ARGS)
if (span->month != 0)
{
j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
j2date(dateVal + POSTGRES_EPOCH_JDATE,
&(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
tm->tm_mon += span->month;
dateVal = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
dateVal = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
}
if (span->time != 0)
dateVal += (span->time / 86400e0);
......@@ -279,9 +280,10 @@ date_mi_interval(PG_FUNCTION_ARGS)
if (span->month != 0)
{
j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
j2date(dateVal + POSTGRES_EPOCH_JDATE,
&(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
tm->tm_mon -= span->month;
dateVal = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
dateVal = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
}
if (span->time != 0)
dateVal -= (span->time / 86400e0);
......@@ -346,7 +348,7 @@ date_timestamptz(PG_FUNCTION_ARGS)
struct tm tt,
*tm = &tt;
j2date((dateVal + date2j(2000, 1, 1)),
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))
......@@ -399,7 +401,7 @@ timestamptz_date(PG_FUNCTION_ARGS)
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to convert timestamp to date");
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
PG_RETURN_DATEADT(result);
}
......@@ -431,7 +433,7 @@ abstime_date(PG_FUNCTION_ARGS)
default:
abstime2tm(abstime, &tz, tm, NULL);
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
break;
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.102 2003/02/22 05:57:44 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.103 2003/04/04 04:50:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -648,6 +648,14 @@ j2date(int jd, int *year, int *month, int *day)
return;
} /* j2date() */
/*
* j2day - convert Julian date to day-of-week (0..6 == Sun..Sat)
*
* Note: various places use the locution j2day(date - 1) to produce a
* result according to the convention 0..6 = Mon..Sun. This is a bit of
* a crock, but will work as long as the computation here is just a modulo.
*/
int
j2day(int date)
{
......@@ -1261,7 +1269,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
*dtype = DTK_DATE;
GetCurrentDateTime(tm);
j2date((date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - 1),
&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
......@@ -1281,7 +1289,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
*dtype = DTK_DATE;
GetCurrentDateTime(tm);
j2date((date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + 1),
&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
......@@ -1546,8 +1554,7 @@ DetermineLocalTimeZone(struct tm * tm)
delta2;
time_t mytime;
day = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) -
date2j(1970, 1, 1));
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;
......@@ -1556,8 +1563,8 @@ DetermineLocalTimeZone(struct tm * tm)
* and reassemble to get a representation of local time.
*/
tmp = localtime(&mytime);
day = (date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
date2j(1970, 1, 1));
day = date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
UNIX_EPOCH_JDATE;
locsec = tmp->tm_sec + (tmp->tm_min + (day * 24 + tmp->tm_hour) * 60) * 60;
/*
......@@ -1586,8 +1593,8 @@ DetermineLocalTimeZone(struct tm * tm)
mysec += delta1;
mytime = (time_t) mysec;
tmp = localtime(&mytime);
day = (date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
date2j(1970, 1, 1));
day = date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
UNIX_EPOCH_JDATE;
locsec = tmp->tm_sec + (tmp->tm_min + (day * 24 + tmp->tm_hour) * 60) * 60;
delta2 = mysec - locsec;
if (delta2 != delta1)
......@@ -1595,8 +1602,8 @@ DetermineLocalTimeZone(struct tm * tm)
mysec += (delta2 - delta1);
mytime = (time_t) mysec;
tmp = localtime(&mytime);
day = (date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
date2j(1970, 1, 1));
day = date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
UNIX_EPOCH_JDATE;
locsec = tmp->tm_sec + (tmp->tm_min + (day * 24 + tmp->tm_hour) * 60) * 60;
delta2 = mysec - locsec;
}
......@@ -2360,7 +2367,7 @@ DecodeNumber(int flen, char *str, int fmask,
{
*tmask = (DTK_M(DOY) | DTK_M(MONTH) | DTK_M(DAY));
tm->tm_yday = val;
j2date((date2j(tm->tm_year, 1, 1) + tm->tm_yday - 1),
j2date(date2j(tm->tm_year, 1, 1) + tm->tm_yday - 1,
&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
}
......@@ -3702,6 +3709,9 @@ CheckDateTokenTables(void)
{
bool ok = true;
Assert(UNIX_EPOCH_JDATE == date2j(1970, 1, 1));
Assert(POSTGRES_EPOCH_JDATE == date2j(2000, 1, 1));
ok &= CheckDateTokenTable("datetktbl", datetktbl, szdatetktbl);
ok &= CheckDateTokenTable("deltatktbl", deltatktbl, szdeltatktbl);
ok &= CheckDateTokenTable("australian_datetktbl",
......
......@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.105 2003/03/20 03:34:56 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.106 2003/04/04 04:50:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -85,10 +85,7 @@ static int istinterval(char *i_string,
/*
* GetCurrentAbsoluteTime()
*
* Get the current system time. Set timezone parameters if not specified
* elsewhere. Define HasCTZSet to allow clients to specify the default
* timezone.
*
* Get the current system time (relative to Unix epoch).
*/
AbsoluteTime
GetCurrentAbsoluteTime(void)
......@@ -100,11 +97,11 @@ GetCurrentAbsoluteTime(void)
}
/* GetCurrentAbsoluteTimeUsec()
* Get the current system time.
/*
* GetCurrentAbsoluteTimeUsec()
*
* Returns the number of seconds since epoch (January 1 1970 GMT),
* and returns fractional seconds (as # of microseconds) into *usec.
* Get the current system time (relative to Unix epoch), including fractional
* seconds expressed as microseconds.
*/
AbsoluteTime
GetCurrentAbsoluteTimeUsec(int *usec)
......@@ -119,7 +116,31 @@ GetCurrentAbsoluteTimeUsec(int *usec)
}
/* GetCurrentDateTime()
/*
* AbsoluteTimeUsecToTimestampTz()
*
* Convert system time including microseconds to TimestampTz representation.
*/
TimestampTz
AbsoluteTimeUsecToTimestampTz(AbsoluteTime sec, int usec)
{
TimestampTz result;
#ifdef HAVE_INT64_TIMESTAMP
result = ((sec - ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * 86400))
* INT64CONST(1000000)) + usec;
#else
result = sec - ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * 86400)
+ (usec / 1000000.0);
#endif
return result;
}
/*
* GetCurrentDateTime()
*
* Get the transaction start time ("now()") broken down as a struct tm.
*/
void
......@@ -131,13 +152,10 @@ GetCurrentDateTime(struct tm * tm)
}
/*
* GetCurrentAbsoluteTimeUsec()
*
* Get the current system time. Set timezone parameters if not specified
* elsewhere. Define HasCTZSet to allow clients to specify the default
* timezone.
* GetCurrentTimeUsec()
*
* Returns the number of seconds since epoch (January 1 1970 GMT)
* Get the transaction start time ("now()") broken down as a struct tm,
* including fractional seconds and timezone offset.
*/
void
GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp)
......@@ -152,7 +170,7 @@ GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp)
#ifdef HAVE_INT64_TIMESTAMP
*fsec = usec;
#else
*fsec = usec * 1.0e-6;
*fsec = usec / 1000000.0;
#endif
}
......@@ -307,7 +325,7 @@ tm2abstime(struct tm * tm, int tz)
|| tm->tm_sec < 0 || tm->tm_sec > 59)
return INVALID_ABSTIME;
day = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(1970, 1, 1));
day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - UNIX_EPOCH_JDATE;
/* check for time out of range */
if ((day < MIN_DAYNUM) || (day > MAX_DAYNUM))
......
......@@ -328,18 +328,7 @@ pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
if (sec == 0 && usec == 0)
PG_RETURN_NULL();
/*
* This method of converting "Unix time" (sec/usec since epoch) to a
* PostgreSQL timestamp is an ugly hack -- if you fix it, be sure to
* fix the similar hackery in timestamp.c
*/
#ifdef HAVE_INT64_TIMESTAMP
result = (((sec - ((date2j(2000, 1, 1) - date2j(1970, 1, 1)) * 86400))
* INT64CONST(1000000)) + usec);
#else
result = (sec + (usec * 1.0e-6) - ((date2j(2000, 1, 1) -
date2j(1970, 1, 1)) * 86400));
#endif
result = AbsoluteTimeUsecToTimestampTz(sec, usec);
PG_RETURN_TIMESTAMPTZ(result);
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.81 2003/03/20 06:02:59 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.82 2003/04/04 04:50:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -728,12 +728,7 @@ now(PG_FUNCTION_ARGS)
sec = GetCurrentTransactionStartTimeUsec(&usec);
#ifdef HAVE_INT64_TIMESTAMP
result = (((sec - ((date2j(2000, 1, 1) - date2j(1970, 1, 1)) * 86400))
* INT64CONST(1000000)) + usec);
#else
result = (sec + (usec * 1.0e-6) - ((date2j(2000, 1, 1) - date2j(1970, 1, 1)) * 86400));
#endif
result = AbsoluteTimeUsecToTimestampTz(sec, usec);
PG_RETURN_TIMESTAMPTZ(result);
}
......@@ -800,7 +795,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
struct tm *tx;
#endif
date0 = date2j(2000, 1, 1);
date0 = POSTGRES_EPOCH_JDATE;
/*
* If HasCTZSet is true then we have a brute force time zone
......@@ -871,9 +866,9 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
{
#ifdef HAVE_INT64_TIMESTAMP
utime = ((dt / INT64CONST(1000000))
+ ((date0 - date2j(1970, 1, 1)) * INT64CONST(86400)));
+ ((date0 - UNIX_EPOCH_JDATE) * INT64CONST(86400)));
#else
utime = (dt + ((date0 - date2j(1970, 1, 1)) * 86400));
utime = (dt + ((date0 - UNIX_EPOCH_JDATE) * 86400));
#endif
#if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
......@@ -960,7 +955,7 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
return -1;
date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
#ifdef HAVE_INT64_TIMESTAMP
*result = ((date * INT64CONST(86400000000)) + time);
......@@ -2675,7 +2670,7 @@ isoweek2date(int woy, int *year, int *mon, int *mday)
day4 = date2j(*year, 1, 4);
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
day0 = j2day(day4 - 1);
dayn = ((woy - 1) * 7) + (day4 - day0);
......@@ -2701,7 +2696,7 @@ date2isoweek(int year, int mon, int mday)
day4 = date2j(year, 1, 4);
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
day0 = j2day(day4 - 1);
/*
* We need the first week containing a Thursday, otherwise this day
......@@ -2709,10 +2704,10 @@ date2isoweek(int year, int mon, int mday)
*/
if (dayn < (day4 - day0))
{
day4 = date2j((year - 1), 1, 4);
day4 = date2j(year - 1, 1, 4);
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
day0 = j2day(day4 - 1);
}
result = (((dayn - (day4 - day0)) / 7) + 1);
......@@ -2723,10 +2718,10 @@ date2isoweek(int year, int mon, int mday)
*/
if (result >= 53)
{
day4 = date2j((year + 1), 1, 4);
day4 = date2j(year + 1, 1, 4);
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
day0 = j2day(day4 - 1);
if (dayn >= (day4 - day0))
result = (((dayn - (day4 - day0)) / 7) + 1);
......
......@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: datetime.h,v 1.36 2003/02/20 05:24:55 tgl Exp $
* $Id: datetime.h,v 1.37 2003/04/04 04:50:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -259,6 +259,10 @@ extern int day_tab[2][13];
|| (((y) == UTIME_MAXYEAR) && (((m) < UTIME_MAXMONTH) \
|| (((m) == UTIME_MAXMONTH) && ((d) <= UTIME_MAXDAY))))))
/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
#define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */
#define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */
extern void GetCurrentDateTime(struct tm * tm);
extern void GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp);
......@@ -289,7 +293,7 @@ extern int EncodeInterval(struct 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 bool ClearDateCache(bool, bool, bool);
extern bool ClearDateCache(bool newval, bool doit, bool interactive);
extern int j2day(int jd);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: nabstime.h,v 1.37 2002/09/01 00:58:07 tgl Exp $
* $Id: nabstime.h,v 1.38 2003/04/04 04:50:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -157,6 +157,7 @@ extern Datum timeofday(PG_FUNCTION_ARGS);
/* non-fmgr-callable support routines */
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);
#endif /* NABSTIME_H */
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