char buf[MAXDATELEN + 1];
time2tm(time, tm, &fsec);
- EncodeTimeOnly(tm, fsec, NULL, DateStyle, buf);
+ EncodeTimeOnly(tm, fsec, false, 0, DateStyle, buf);
result = pstrdup(buf);
PG_RETURN_CSTRING(result);
char buf[MAXDATELEN + 1];
timetz2tm(time, tm, &fsec, &tz);
- EncodeTimeOnly(tm, fsec, &tz, DateStyle, buf);
+ EncodeTimeOnly(tm, fsec, true, tz, DateStyle, buf);
result = pstrdup(buf);
PG_RETURN_CSTRING(result);
/* EncodeTimeOnly()
* Encode time fields only.
+ *
+ * tm and fsec are the value to encode, print_tz determines whether to include
+ * a time zone (the difference between time and timetz types), tz is the
+ * numeric time zone offset, style is the date style, str is where to write the
+ * output.
*/
void
-EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, int *tzp, int style, char *str)
+EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, bool print_tz, int tz, int style, char *str)
{
sprintf(str, "%02d:%02d:", tm->tm_hour, tm->tm_min);
str += strlen(str);
AppendSeconds(str, tm->tm_sec, fsec, MAX_TIME_PRECISION, true);
- if (tzp != NULL)
- EncodeTimezone(str, *tzp, style);
+ if (print_tz)
+ EncodeTimezone(str, tz, style);
}
/* EncodeDateTime()
* Encode date and time interpreted as local time.
- * Support several date styles:
+ *
+ * tm and fsec are the value to encode, print_tz determines whether to include
+ * a time zone (the difference between timestamp and timestamptz types), tz is
+ * the numeric time zone offset, tzn is the textual time zone, which if
+ * specified will be used instead of tz by some styles, style is the date
+ * style, str is where to write the output.
+ *
+ * Supported date styles:
* Postgres - day mon hh:mm:ss yyyy tz
* SQL - mm/dd/yyyy hh:mm:ss.ss tz
* ISO - yyyy-mm-dd hh:mm:ss+/-tz
* German - dd.mm.yyyy hh:mm:ss tz
* XSD - yyyy-mm-ddThh:mm:ss.ss+/-tz
- * Variants (affects order of month and day for Postgres and SQL styles):
- * US - mm/dd/yyyy
- * European - dd/mm/yyyy
*/
void
-EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str)
+EncodeDateTime(struct pg_tm * tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
{
int day;
Assert(tm->tm_mon >= 1 && tm->tm_mon <= MONTHS_PER_YEAR);
+ /*
+ * Negative tm_isdst means we have no valid time zone translation.
+ */
+ if (tm->tm_isdst < 0)
+ print_tz = false;
+
switch (style)
{
case USE_ISO_DATES:
AppendTimestampSeconds(str + strlen(str), tm, fsec);
- /*
- * tzp == NULL indicates that we don't want *any* time zone info
- * in the output string. *tzn != NULL indicates that we have alpha
- * time zone info available. tm_isdst != -1 indicates that we have
- * a valid time zone translation.
- */
- if (tzp != NULL && tm->tm_isdst >= 0)
- EncodeTimezone(str, *tzp, style);
+ if (print_tz)
+ EncodeTimezone(str, tz, style);
if (tm->tm_year <= 0)
sprintf(str + strlen(str), " BC");
* TZ abbreviations in the Olson database are plain ASCII.
*/
- if (tzp != NULL && tm->tm_isdst >= 0)
+ if (print_tz)
{
- if (*tzn != NULL)
- sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);
+ if (tzn)
+ sprintf(str + strlen(str), " %.*s", MAXTZLEN, tzn);
else
- EncodeTimezone(str, *tzp, style);
+ EncodeTimezone(str, tz, style);
}
if (tm->tm_year <= 0)
AppendTimestampSeconds(str + strlen(str), tm, fsec);
- if (tzp != NULL && tm->tm_isdst >= 0)
+ if (print_tz)
{
- if (*tzn != NULL)
- sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);
+ if (tzn)
+ sprintf(str + strlen(str), " %.*s", MAXTZLEN, tzn);
else
- EncodeTimezone(str, *tzp, style);
+ EncodeTimezone(str, tz, style);
}
if (tm->tm_year <= 0)
sprintf(str + strlen(str), " %04d",
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1));
- if (tzp != NULL && tm->tm_isdst >= 0)
+ if (print_tz)
{
- if (*tzn != NULL)
- sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);
+ if (tzn)
+ sprintf(str + strlen(str), " %.*s", MAXTZLEN, tzn);
else
{
/*
* the date/time parser later. - thomas 2001-10-19
*/
sprintf(str + strlen(str), " ");
- EncodeTimezone(str, *tzp, style);
+ EncodeTimezone(str, tz, style);
}
}
break;
default:
abstime2tm(time, &tz, tm, &tzn);
- EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
+ EncodeDateTime(tm, fsec, true, tz, tzn, DateStyle, buf);
break;
}
struct pg_tm tt,
*tm = &tt;
fsec_t fsec;
- char *tzn = NULL;
char buf[MAXDATELEN + 1];
if (TIMESTAMP_NOT_FINITE(timestamp))
EncodeSpecialTimestamp(timestamp, buf);
else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
- EncodeDateTime(tm, fsec, NULL, &tzn, DateStyle, buf);
+ EncodeDateTime(tm, fsec, false, 0, NULL, DateStyle, buf);
else
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
if (TIMESTAMP_NOT_FINITE(dt))
EncodeSpecialTimestamp(dt, buf);
else if (timestamp2tm(dt, &tz, tm, &fsec, &tzn, NULL) == 0)
- EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
+ EncodeDateTime(tm, fsec, true, tz, tzn, DateStyle, buf);
else
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
if (TIMESTAMP_NOT_FINITE(t))
EncodeSpecialTimestamp(t, buf);
else if (timestamp2tm(t, &tz, tm, &fsec, &tzn, NULL) == 0)
- EncodeDateTime(tm, fsec, &tz, &tzn, USE_ISO_DATES, buf);
+ EncodeDateTime(tm, fsec, true, tz, tzn, USE_ISO_DATES, buf);
else
strlcpy(buf, "(timestamp out of range)", sizeof(buf));
Timestamp timestamp;
struct pg_tm tm;
fsec_t fsec;
- char *tzn = NULL;
char buf[MAXDATELEN + 1];
timestamp = DatumGetTimestamp(value);
errmsg("timestamp out of range"),
errdetail("XML does not support infinite timestamp values.")));
else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
- EncodeDateTime(&tm, fsec, NULL, &tzn, USE_XSD_DATES, buf);
+ EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
else
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range"),
errdetail("XML does not support infinite timestamp values.")));
else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
- EncodeDateTime(&tm, fsec, &tz, &tzn, USE_XSD_DATES, buf);
+ EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
else
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
extern int DetermineTimeZoneOffset(struct pg_tm * tm, pg_tz *tzp);
extern void EncodeDateOnly(struct pg_tm * tm, int style, char *str);
-extern void EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, int *tzp, int style, char *str);
-extern void EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str);
+extern void EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, bool print_tz, int tz, int style, char *str);
+extern void EncodeDateTime(struct pg_tm * tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str);
extern void EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str);
extern int DecodeSpecial(int field, char *lowtoken, int *val);
int DecodeInterval(char **, int *, int, int *, struct tm *, fsec_t *);
int DecodeTime(char *, int *, struct tm *, fsec_t *);
-int EncodeDateTime(struct tm *, fsec_t, int *, char **, int, char *, bool);
-int EncodeInterval(struct tm *, fsec_t, int, char *);
+int EncodeDateTime(struct tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str, bool EuroDates);
+int EncodeInterval(struct tm *tm, fsec_t fsec, int style, char *str);
int tm2timestamp(struct tm *, fsec_t, int *, timestamp *);
int DecodeUnits(int field, char *lowtoken, int *val);
bool CheckDateTokenTables(void);
-int EncodeDateOnly(struct tm *, int, char *, bool);
+int EncodeDateOnly(struct tm *tm, int style, char *str, bool EuroDates);
int GetEpochTime(struct tm *);
int ParseDateTime(char *, char *, char **, int *, int *, char **);
int DecodeDateTime(char **, int *, int, int *, struct tm *, fsec_t *, bool);
/* EncodeDateTime()
* Encode date and time interpreted as local time.
- * Support several date styles:
+ *
+ * tm and fsec are the value to encode, print_tz determines whether to include
+ * a time zone (the difference between timestamp and timestamptz types), tz is
+ * the numeric time zone offset, tzn is the textual time zone, which if
+ * specified will be used instead of tz by some styles, style is the date
+ * style, str is where to write the output.
+ *
+ * Supported date styles:
* Postgres - day mon hh:mm:ss yyyy tz
* SQL - mm/dd/yyyy hh:mm:ss.ss tz
* ISO - yyyy-mm-dd hh:mm:ss+/-tz
* European - dd/mm/yyyy
*/
int
-EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str, bool EuroDates)
+EncodeDateTime(struct tm * tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str, bool EuroDates)
{
int day,
hour,
min;
+ /*
+ * Negative tm_isdst means we have no valid time zone translation.
+ */
+ if (tm->tm_isdst < 0)
+ print_tz = false;
+
switch (style)
{
case USE_ISO_DATES:
if (tm->tm_year <= 0)
sprintf(str + strlen(str), " BC");
- /*
- * tzp == NULL indicates that we don't want *any* time zone info
- * in the output string. *tzn != NULL indicates that we have alpha
- * time zone info available. tm_isdst != -1 indicates that we have
- * a valid time zone translation.
- */
- if (tzp != NULL && tm->tm_isdst >= 0)
+ if (print_tz)
{
- hour = -(*tzp / SECS_PER_HOUR);
- min = (abs(*tzp) / MINS_PER_HOUR) % MINS_PER_HOUR;
+ hour = -(tz / SECS_PER_HOUR);
+ min = (abs(tz) / MINS_PER_HOUR) % MINS_PER_HOUR;
if (min != 0)
sprintf(str + strlen(str), "%+03d:%02d", hour, min);
else
* TZ abbreviations in the Olson database are plain ASCII.
*/
- if (tzp != NULL && tm->tm_isdst >= 0)
+ if (print_tz)
{
- if (*tzn != NULL)
- sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);
+ if (tzn)
+ sprintf(str + strlen(str), " %.*s", MAXTZLEN, tzn);
else
{
- hour = -(*tzp / SECS_PER_HOUR);
- min = (abs(*tzp) / MINS_PER_HOUR) % MINS_PER_HOUR;
+ hour = -(tz / SECS_PER_HOUR);
+ min = (abs(tz) / MINS_PER_HOUR) % MINS_PER_HOUR;
if (min != 0)
sprintf(str + strlen(str), "%+03d:%02d", hour, min);
else
if (tm->tm_year <= 0)
sprintf(str + strlen(str), " BC");
- if (tzp != NULL && tm->tm_isdst >= 0)
+ if (print_tz)
{
- if (*tzn != NULL)
- sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);
+ if (tzn)
+ sprintf(str + strlen(str), " %.*s", MAXTZLEN, tzn);
else
{
- hour = -(*tzp / SECS_PER_HOUR);
- min = (abs(*tzp) / MINS_PER_HOUR) % MINS_PER_HOUR;
+ hour = -(tz / SECS_PER_HOUR);
+ min = (abs(tz) / MINS_PER_HOUR) % MINS_PER_HOUR;
if (min != 0)
sprintf(str + strlen(str), "%+03d:%02d", hour, min);
else
if (tm->tm_year <= 0)
sprintf(str + strlen(str), " BC");
- if (tzp != NULL && tm->tm_isdst >= 0)
+ if (print_tz)
{
- if (*tzn != NULL)
- sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);
+ if (tzn)
+ sprintf(str + strlen(str), " %.*s", MAXTZLEN, tzn);
else
{
/*
* avoid formatting something which would be rejected by
* the date/time parser later. - thomas 2001-10-19
*/
- hour = -(*tzp / SECS_PER_HOUR);
- min = (abs(*tzp) / MINS_PER_HOUR) % MINS_PER_HOUR;
+ hour = -(tz / SECS_PER_HOUR);
+ min = (abs(tz) / MINS_PER_HOUR) % MINS_PER_HOUR;
if (min != 0)
sprintf(str + strlen(str), " %+03d:%02d", hour, min);
else
struct tm tt,
*tm = &tt;
char buf[MAXDATELEN + 1];
- char *tzn = NULL;
fsec_t fsec;
int DateStyle = 1; /* this defaults to ISO_DATES, shall we make
* it an option? */
if (TIMESTAMP_NOT_FINITE(tstamp))
EncodeSpecialTimestamp(tstamp, buf);
else if (timestamp2tm(tstamp, NULL, tm, &fsec, NULL) == 0)
- EncodeDateTime(tm, fsec, NULL, &tzn, DateStyle, buf, 0);
+ EncodeDateTime(tm, fsec, false, 0, NULL, DateStyle, buf, 0);
else
{
errno = PGTYPES_TS_BAD_TIMESTAMP;