#else
myextra.CTimeZone = -interval->time;
#endif
+ myextra.session_timezone = pg_tzset_offset(myextra.CTimeZone);
myextra.HasCTZSet = true;
pfree(interval);
{
/* Here we change from SQL to Unix sign convention */
myextra.CTimeZone = -hours * SECS_PER_HOUR;
+ myextra.session_timezone = pg_tzset_offset(myextra.CTimeZone);
myextra.HasCTZSet = true;
}
else
after_isdst;
int res;
- if (tzp == session_timezone && 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
extern void pg_timezone_initialize(void);
extern pg_tz *pg_tzset(const char *tzname);
+extern pg_tz *pg_tzset_offset(long gmtoffset);
extern pg_tzenum *pg_tzenumerate_start(void);
extern pg_tz *pg_tzenumerate_next(pg_tzenum *dir);
SELECT to_timestamp('10000000000', 'FMYYYY');
ERROR: value for "YYYY" in source string is out of range
DETAIL: Value must be in the range -2147483648 to 2147483647.
+--
+-- Check behavior with SQL-style fixed-GMT-offset time zone (cf bug #8572)
+--
+SET TIME ZONE 'America/New_York';
+SET TIME ZONE '-1.5';
+SHOW TIME ZONE;
+ TimeZone
+----------------------
+ @ 1 hour 30 mins ago
+(1 row)
+
+SELECT '2012-12-12 12:00'::timestamptz;
+ timestamptz
+---------------------------------
+ Wed Dec 12 12:00:00 2012 -01:30
+(1 row)
+
+SELECT '2012-12-12 12:00 America/New_York'::timestamptz;
+ timestamptz
+---------------------------------
+ Wed Dec 12 15:30:00 2012 -01:30
+(1 row)
+
+SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ');
+ to_char
+----------------------
+ 2012-12-12 12:00:00
+(1 row)
+
+RESET TIME ZONE;
-- Input that doesn't fit in an int:
SELECT to_timestamp('10000000000', 'FMYYYY');
+
+--
+-- Check behavior with SQL-style fixed-GMT-offset time zone (cf bug #8572)
+--
+
+SET TIME ZONE 'America/New_York';
+SET TIME ZONE '-1.5';
+
+SHOW TIME ZONE;
+
+SELECT '2012-12-12 12:00'::timestamptz;
+SELECT '2012-12-12 12:00 America/New_York'::timestamptz;
+
+SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ');
+
+RESET TIME ZONE;
return &tzp->tz;
}
+/*
+ * Load a fixed-GMT-offset timezone.
+ * This is used for SQL-spec SET TIME ZONE INTERVAL 'foo' cases.
+ * It's otherwise equivalent to pg_tzset().
+ *
+ * The GMT offset is specified in seconds, positive values meaning west of
+ * Greenwich (ie, POSIX not ISO sign convention). However, we use ISO
+ * sign convention in the displayable abbreviation for the zone.
+ */
+pg_tz *
+pg_tzset_offset(long gmtoffset)
+{
+ long absoffset = (gmtoffset < 0) ? -gmtoffset : gmtoffset;
+ char offsetstr[64];
+ char tzname[128];
+
+ snprintf(offsetstr, sizeof(offsetstr),
+ "%02ld", absoffset / SECSPERHOUR);
+ absoffset %= SECSPERHOUR;
+ if (absoffset != 0)
+ {
+ snprintf(offsetstr + strlen(offsetstr),
+ sizeof(offsetstr) - strlen(offsetstr),
+ ":%02ld", absoffset / SECSPERMIN);
+ absoffset %= SECSPERMIN;
+ if (absoffset != 0)
+ snprintf(offsetstr + strlen(offsetstr),
+ sizeof(offsetstr) - strlen(offsetstr),
+ ":%02ld", absoffset);
+ }
+ if (gmtoffset > 0)
+ snprintf(tzname, sizeof(tzname), "<-%s>+%s",
+ offsetstr, offsetstr);
+ else
+ snprintf(tzname, sizeof(tzname), "<+%s>-%s",
+ offsetstr, offsetstr);
+
+ return pg_tzset(tzname);
+}
+
/*
* Initialize timezone library