aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/datetime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/datetime.c')
-rw-r--r--src/backend/utils/adt/datetime.c82
1 files changed, 73 insertions, 9 deletions
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 1418a0c34c2..3c88ac3a3d1 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.42 2000/02/16 18:17:02 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.43 2000/03/14 23:06:36 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -618,8 +618,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
tm->tm_min = 0;
tm->tm_sec = 0;
*fsec = 0;
- tm->tm_isdst = -1; /* don't know daylight savings time status
- * apriori */
+ tm->tm_isdst = -1; /* don't know daylight savings time status apriori */
if (tzp != NULL)
*tzp = 0;
@@ -897,8 +896,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
tm->tm_mon += 1;
#if defined(HAVE_TM_ZONE)
- *tzp = -(tm->tm_gmtoff); /* tm_gmtoff is
- * Sun/DEC-ism */
+ *tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
#elif defined(HAVE_INT_TIMEZONE)
#ifdef __CYGWIN__
*tzp = ((tm->tm_isdst > 0) ? (_timezone - 3600) : _timezone);
@@ -927,9 +925,18 @@ DecodeDateTime(char **field, int *ftype, int nf,
/* DecodeTimeOnly()
* Interpret parsed string as time fields only.
+ * Note that support for time zone is here for
+ * SQL92 TIME WITH TIME ZONE, but it reveals
+ * bogosity with SQL92 date/time standards, since
+ * we must infer a time zone from current time.
+ * XXX Later, we should probably support
+ * SET TIME ZONE <integer>
+ * which of course is a screwed up convention.
+ * - thomas 2000-03-10
*/
int
-DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, double *fsec)
+DecodeTimeOnly(char **field, int *ftype, int nf,
+ int *dtype, struct tm * tm, double *fsec, int *tzp)
{
int fmask,
tmask,
@@ -944,9 +951,10 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
- tm->tm_isdst = -1; /* don't know daylight savings time status
- * apriori */
*fsec = 0;
+ tm->tm_isdst = -1; /* don't know daylight savings time status apriori */
+ if (tzp != NULL)
+ *tzp = 0;
fmask = DTK_DATE_M;
@@ -959,6 +967,14 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
return -1;
break;
+ case DTK_TZ:
+ if (tzp == NULL)
+ return -1;
+ if (DecodeTimezone(field[i], tzp) != 0)
+ return -1;
+ tmask = DTK_M(TZ);
+ break;
+
case DTK_NUMBER:
flen = strlen(field[i]);
@@ -1035,6 +1051,45 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
if ((fmask & DTK_TIME_M) != DTK_TIME_M)
return -1;
+ /* timezone not specified? then find local timezone if possible */
+ if ((tzp != NULL) && (!(fmask & DTK_M(TZ))))
+ {
+ struct tm tt, *tmp = &tt;
+
+ /*
+ * daylight savings time modifier but no standard timezone?
+ * then error
+ */
+ if (fmask & DTK_M(DTZMOD))
+ return -1;
+
+ GetCurrentTime(tmp);
+ tmp->tm_hour = tm->tm_hour;
+ tmp->tm_min = tm->tm_min;
+ tmp->tm_sec = tm->tm_sec;
+
+#ifdef USE_POSIX_TIME
+ tmp->tm_isdst = -1;
+ mktime(tmp);
+ tm->tm_isdst = tmp->tm_isdst;
+
+#if defined(HAVE_TM_ZONE)
+ *tzp = -(tmp->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
+#elif defined(HAVE_INT_TIMEZONE)
+#ifdef __CYGWIN__
+ *tzp = ((tmp->tm_isdst > 0) ? (_timezone - 3600) : _timezone);
+#else
+ *tzp = ((tmp->tm_isdst > 0) ? (timezone - 3600) : timezone);
+#endif
+#else
+#error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined
+#endif
+
+#else /* !USE_POSIX_TIME */
+ *tzp = CTimeZone;
+#endif
+ }
+
return 0;
} /* DecodeTimeOnly() */
@@ -1830,7 +1885,7 @@ EncodeDateOnly(struct tm * tm, int style, char *str)
* Encode time fields only.
*/
int
-EncodeTimeOnly(struct tm * tm, double fsec, int style, char *str)
+EncodeTimeOnly(struct tm * tm, double fsec, int *tzp, int style, char *str)
{
double sec;
@@ -1842,6 +1897,15 @@ EncodeTimeOnly(struct tm * tm, double fsec, int style, char *str)
sprintf(str, "%02d:%02d:", tm->tm_hour, tm->tm_min);
sprintf((str + 6), ((fsec != 0) ? "%05.2f" : "%02.0f"), sec);
+ if (tzp != NULL)
+ {
+ int hour, min;
+
+ hour = -(*tzp / 3600);
+ min = ((abs(*tzp) / 60) % 60);
+ sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
+ }
+
return TRUE;
} /* EncodeTimeOnly() */