Skip to content

Commit 0b35b01

Browse files
committed
Arrange for timezone names to be recognized case-insensitively; for
example SET TIME ZONE 'america/new_york' works now. This seems a good idea on general user-friendliness grounds, and is part of the solution to the timestamp-input parsing problems I noted recently.
1 parent a2ebf81 commit 0b35b01

File tree

5 files changed

+195
-78
lines changed

5 files changed

+195
-78
lines changed

doc/src/sgml/datatype.sgml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.176 2006/09/22 16:20:00 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.177 2006/10/16 19:58:26 tgl Exp $ -->
22

33
<chapter id="datatype">
44
<title id="datatype-title">Data Types</title>
@@ -1593,12 +1593,12 @@ SELECT b, char_length(b) FROM test2;
15931593
linkend="datatype-datetime-time-table">
15941594
and <xref linkend="datatype-timezone-table">.) If a time zone is
15951595
specified in the input for <type>time without time zone</type>,
1596-
it is silently ignored. You can also always specify a date but it will
1597-
be ignored except for when you use a full time zone name like
1596+
it is silently ignored. You can also specify a date but it will
1597+
be ignored, except when you use a full time zone name like
15981598
<literal>America/New_York</literal>. In this case specifying the date
1599-
is compulsory in order to tell which time zone offset should be
1600-
applied. It will be applied whatever time zone offset was valid at that
1601-
date and time at the specified place.
1599+
is required in order to determine whether standard or daylight-savings
1600+
time applies. The appropriate time zone offset is recorded in the
1601+
<type>time with time zone</type> value.
16021602
</para>
16031603

16041604
<table id="datatype-datetime-time-table">
@@ -1653,7 +1653,7 @@ SELECT b, char_length(b) FROM test2;
16531653
</row>
16541654
<row>
16551655
<entry><literal>04:05:06 PST</literal></entry>
1656-
<entry>time zone specified by name</entry>
1656+
<entry>time zone specified by abbreviation</entry>
16571657
</row>
16581658
<row>
16591659
<entry><literal>2003-04-12 04:05:06 America/New_York</literal></entry>
@@ -2214,6 +2214,12 @@ January 8 04:05:06 1999 PST
22142214
will always know the correct UTC offset for your region.
22152215
</para>
22162216

2217+
<para>
2218+
In all cases, timezone names are recognized case-insensitively.
2219+
(This is a change from <productname>PostgreSQL</productname> versions
2220+
prior to 8.2, which were case-sensitive in some contexts and not others.)
2221+
</para>
2222+
22172223
<para>
22182224
Note that timezone names are <emphasis>not</> used for date/time output
22192225
&mdash; all supported output formats use numeric timezone displays to

src/timezone/localtime.c

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/timezone/localtime.c,v 1.14 2006/06/07 22:24:46 momjian Exp $
6+
* $PostgreSQL: pgsql/src/timezone/localtime.c,v 1.15 2006/10/16 19:58:26 tgl Exp $
77
*/
88

99
/*
@@ -122,44 +122,19 @@ detzcode(const char *codep)
122122
}
123123

124124
int
125-
tzload(const char *name, struct state * sp)
125+
tzload(const char *name, char *canonname, struct state *sp)
126126
{
127127
const char *p;
128128
int i;
129129
int fid;
130130

131131
if (name == NULL && (name = TZDEFAULT) == NULL)
132132
return -1;
133-
{
134-
int doaccess;
135-
char fullname[MAXPGPATH];
136-
137-
if (name[0] == ':')
138-
++name;
139-
doaccess = name[0] == '/';
140-
if (!doaccess)
141-
{
142-
p = pg_TZDIR();
143-
if (p == NULL)
144-
return -1;
145-
if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
146-
return -1;
147-
(void) strcpy(fullname, p);
148-
(void) strcat(fullname, "/");
149-
(void) strcat(fullname, name);
150-
151-
/*
152-
* Set doaccess if '.' (as in "../") shows up in name.
153-
*/
154-
if (strchr(name, '.') != NULL)
155-
doaccess = TRUE;
156-
name = fullname;
157-
}
158-
if (doaccess && access(name, R_OK) != 0)
159-
return -1;
160-
if ((fid = open(name, O_RDONLY | PG_BINARY, 0)) == -1)
161-
return -1;
162-
}
133+
if (name[0] == ':')
134+
++name;
135+
fid = pg_open_tzfile(name, canonname);
136+
if (fid < 0)
137+
return -1;
163138
{
164139
struct tzhead *tzhp;
165140
union
@@ -587,7 +562,7 @@ tzparse(const char *name, struct state * sp, int lastditch)
587562
if (name == NULL)
588563
return -1;
589564
}
590-
load_result = tzload(TZDEFRULES, sp);
565+
load_result = tzload(TZDEFRULES, NULL, sp);
591566
if (load_result != 0)
592567
sp->leapcnt = 0; /* so, we're off a little */
593568
if (*name != '\0')
@@ -794,7 +769,7 @@ tzparse(const char *name, struct state * sp, int lastditch)
794769
static void
795770
gmtload(struct state * sp)
796771
{
797-
if (tzload(gmt, sp) != 0)
772+
if (tzload(gmt, NULL, sp) != 0)
798773
(void) tzparse(gmt, sp, TRUE);
799774
}
800775

0 commit comments

Comments
 (0)