Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit11b623d

Browse files
committed
Implement TZH and TZM timestamp format patterns
These are compatible with Oracle and required for the datetime templatelanguage for jsonpath in an upcoming patch.Nikita Glukhov and Andrew Dunstan, reviewed by Pavel Stehule.
1 parenta77dd53 commit11b623d

File tree

6 files changed

+164
-41
lines changed

6 files changed

+164
-41
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6073,6 +6073,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
60736073
<entry>lower case time-zone abbreviation
60746074
(only supported in <function>to_char</function>)</entry>
60756075
</row>
6076+
<row>
6077+
<entry><literal>TZH</literal></entry>
6078+
<entry>time-zone hours</entry>
6079+
</row>
6080+
<row>
6081+
<entry><literal>TZM</literal></entry>
6082+
<entry>time-zone minutes</entry>
6083+
</row>
60766084
<row>
60776085
<entry><literal>OF</literal></entry>
60786086
<entry>time-zone offset from UTC

‎src/backend/utils/adt/formatting.c

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,10 @@ typedef struct
424424
j,
425425
us,
426426
yysz,/* is it YY or YYYY ? */
427-
clock;/* 12 or 24 hour clock? */
427+
clock,/* 12 or 24 hour clock? */
428+
tzsign,/* +1, -1 or 0 if timezone info is absent */
429+
tzh,
430+
tzm;
428431
}TmFromChar;
429432

430433
#defineZERO_tmfc(_X) memset(_X, 0, sizeof(TmFromChar))
@@ -470,6 +473,7 @@ do {\
470473
(_X)->tm_sec = (_X)->tm_year = (_X)->tm_min = (_X)->tm_wday = \
471474
(_X)->tm_hour = (_X)->tm_yday = (_X)->tm_isdst = 0; \
472475
(_X)->tm_mday = (_X)->tm_mon = 1; \
476+
(_X)->tm_zone = NULL; \
473477
} while(0)
474478

475479
#defineZERO_tmtc(_X) \
@@ -609,6 +613,8 @@ typedef enum
609613
DCH_RM,
610614
DCH_SSSS,
611615
DCH_SS,
616+
DCH_TZH,
617+
DCH_TZM,
612618
DCH_TZ,
613619
DCH_US,
614620
DCH_WW,
@@ -756,7 +762,9 @@ static const KeyWord DCH_keywords[] = {
756762
{"RM",2,DCH_RM, false,FROM_CHAR_DATE_GREGORIAN},/* R */
757763
{"SSSS",4,DCH_SSSS, true,FROM_CHAR_DATE_NONE},/* S */
758764
{"SS",2,DCH_SS, true,FROM_CHAR_DATE_NONE},
759-
{"TZ",2,DCH_TZ, false,FROM_CHAR_DATE_NONE},/* T */
765+
{"TZH",3,DCH_TZH, false,FROM_CHAR_DATE_NONE},/* T */
766+
{"TZM",3,DCH_TZM, true,FROM_CHAR_DATE_NONE},
767+
{"TZ",2,DCH_TZ, false,FROM_CHAR_DATE_NONE},
760768
{"US",2,DCH_US, true,FROM_CHAR_DATE_NONE},/* U */
761769
{"WW",2,DCH_WW, true,FROM_CHAR_DATE_GREGORIAN},/* W */
762770
{"W",1,DCH_W, true,FROM_CHAR_DATE_GREGORIAN},
@@ -879,7 +887,7 @@ static const int DCH_index[KeyWord_INDEX_SIZE] = {
879887
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
880888
-1,-1,-1,-1,-1,DCH_A_D,DCH_B_C,DCH_CC,DCH_DAY,-1,
881889
DCH_FX,-1,DCH_HH24,DCH_IDDD,DCH_J,-1,-1,DCH_MI,-1,DCH_OF,
882-
DCH_P_M,DCH_Q,DCH_RM,DCH_SSSS,DCH_TZ,DCH_US,-1,DCH_WW,-1,DCH_Y_YYY,
890+
DCH_P_M,DCH_Q,DCH_RM,DCH_SSSS,DCH_TZH,DCH_US,-1,DCH_WW,-1,DCH_Y_YYY,
883891
-1,-1,-1,-1,-1,-1,-1,DCH_a_d,DCH_b_c,DCH_cc,
884892
DCH_day,-1,DCH_fx,-1,DCH_hh24,DCH_iddd,DCH_j,-1,-1,DCH_mi,
885893
-1,-1,DCH_p_m,DCH_q,DCH_rm,DCH_ssss,DCH_tz,DCH_us,-1,DCH_ww,
@@ -2519,6 +2527,19 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
25192527
s+=strlen(s);
25202528
}
25212529
break;
2530+
caseDCH_TZH:
2531+
INVALID_FOR_INTERVAL;
2532+
sprintf(s,"%c%02d",
2533+
(tm->tm_gmtoff >=0) ?'+' :'-',
2534+
abs((int)tm->tm_gmtoff) /SECS_PER_HOUR);
2535+
s+=strlen(s);
2536+
break;
2537+
caseDCH_TZM:
2538+
INVALID_FOR_INTERVAL;
2539+
sprintf(s,"%02d",
2540+
(abs((int)tm->tm_gmtoff) %SECS_PER_HOUR) /SECS_PER_MINUTE);
2541+
s+=strlen(s);
2542+
break;
25222543
caseDCH_OF:
25232544
INVALID_FOR_INTERVAL;
25242545
sprintf(s,"%c%0*d",
@@ -3070,6 +3091,20 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
30703091
errmsg("formatting field \"%s\" is only supported in to_char",
30713092
n->key->name)));
30723093
break;
3094+
caseDCH_TZH:
3095+
out->tzsign=*s=='-' ?-1 :+1;
3096+
3097+
if (*s=='+'||*s=='-'||*s==' ')
3098+
s++;
3099+
3100+
from_char_parse_int_len(&out->tzh,&s,2,n);
3101+
break;
3102+
caseDCH_TZM:
3103+
/* assign positive timezone sign if TZH was not seen before */
3104+
if (!out->tzsign)
3105+
out->tzsign=+1;
3106+
from_char_parse_int_len(&out->tzm,&s,2,n);
3107+
break;
30733108
caseDCH_A_D:
30743109
caseDCH_B_C:
30753110
caseDCH_a_d:
@@ -3536,7 +3571,16 @@ to_timestamp(PG_FUNCTION_ARGS)
35363571

35373572
do_to_timestamp(date_txt,fmt,&tm,&fsec);
35383573

3539-
tz=DetermineTimeZoneOffset(&tm,session_timezone);
3574+
/* Use the specified time zone, if any. */
3575+
if (tm.tm_zone)
3576+
{
3577+
intdterr=DecodeTimezone((char*)tm.tm_zone,&tz);
3578+
3579+
if (dterr)
3580+
DateTimeParseError(dterr,text_to_cstring(date_txt),"timestamptz");
3581+
}
3582+
else
3583+
tz=DetermineTimeZoneOffset(&tm,session_timezone);
35403584

35413585
if (tm2timestamp(&tm,fsec,&tz,&result)!=0)
35423586
ereport(ERROR,
@@ -3858,6 +3902,23 @@ do_to_timestamp(text *date_txt, text *fmt,
38583902
*fsec<INT64CONST(0)||*fsec >=USECS_PER_SEC)
38593903
DateTimeParseError(DTERR_FIELD_OVERFLOW,date_str,"timestamp");
38603904

3905+
/* Save parsed time-zone into tm->tm_zone if it was specified */
3906+
if (tmfc.tzsign)
3907+
{
3908+
char*tz;
3909+
3910+
if (tmfc.tzh<0||tmfc.tzh>MAX_TZDISP_HOUR||
3911+
tmfc.tzm<0||tmfc.tzm >=MINS_PER_HOUR)
3912+
DateTimeParseError(DTERR_TZDISP_OVERFLOW,date_str,"timestamp");
3913+
3914+
tz=palloc(7);
3915+
3916+
snprintf(tz,7,"%c%02d:%02d",
3917+
tmfc.tzsign>0 ?'+' :'-',tmfc.tzh,tmfc.tzm);
3918+
3919+
tm->tm_zone=tz;
3920+
}
3921+
38613922
DEBUG_TM(tm);
38623923

38633924
pfree(date_str);

‎src/test/regress/expected/horology.out

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2930,6 +2930,36 @@ SELECT to_timestamp('2011-12-18 11:38 PM', 'YYYY-MM-DD HH12:MI PM');
29302930
Sun Dec 18 23:38:00 2011 PST
29312931
(1 row)
29322932

2933+
SELECT to_timestamp('2011-12-18 11:38 +05', 'YYYY-MM-DD HH12:MI TZH');
2934+
to_timestamp
2935+
------------------------------
2936+
Sat Dec 17 22:38:00 2011 PST
2937+
(1 row)
2938+
2939+
SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI TZH');
2940+
to_timestamp
2941+
------------------------------
2942+
Sun Dec 18 08:38:00 2011 PST
2943+
(1 row)
2944+
2945+
SELECT to_timestamp('2011-12-18 11:38 +05:20', 'YYYY-MM-DD HH12:MI TZH:TZM');
2946+
to_timestamp
2947+
------------------------------
2948+
Sat Dec 17 22:18:00 2011 PST
2949+
(1 row)
2950+
2951+
SELECT to_timestamp('2011-12-18 11:38 -05:20', 'YYYY-MM-DD HH12:MI TZH:TZM');
2952+
to_timestamp
2953+
------------------------------
2954+
Sun Dec 18 08:58:00 2011 PST
2955+
(1 row)
2956+
2957+
SELECT to_timestamp('2011-12-18 11:38 20', 'YYYY-MM-DD HH12:MI TZM');
2958+
to_timestamp
2959+
------------------------------
2960+
Sun Dec 18 03:18:00 2011 PST
2961+
(1 row)
2962+
29332963
--
29342964
-- Check handling of multiple spaces in format and/or input
29352965
--

‎src/test/regress/expected/timestamptz.out

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,54 +1699,68 @@ SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID')
16991699
| 2001 1 1 1 1 1 1
17001700
(66 rows)
17011701

1702-
-- Check OF with various zone offsets, particularly fractional hours
1702+
-- Check OF, TZH, TZM with various zone offsets, particularly fractional hours
17031703
SET timezone = '00:00';
1704-
SELECT to_char(now(), 'OF');
1705-
to_char
1706-
---------
1707-
+00
1704+
SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM";
1705+
OF | TZH:TZM
1706+
-----+---------
1707+
+00 | +00:00
17081708
(1 row)
17091709

17101710
SET timezone = '+02:00';
1711-
SELECT to_char(now(), 'OF');
1712-
to_char
1713-
---------
1714-
-02
1711+
SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM";
1712+
OF | TZH:TZM
1713+
-----+---------
1714+
-02 | -02:00
17151715
(1 row)
17161716

17171717
SET timezone = '-13:00';
1718-
SELECT to_char(now(), 'OF');
1719-
to_char
1720-
---------
1721-
+13
1718+
SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM";
1719+
OF | TZH:TZM
1720+
-----+---------
1721+
+13 | +13:00
17221722
(1 row)
17231723

17241724
SET timezone = '-00:30';
1725-
SELECT to_char(now(), 'OF');
1726-
to_char
1727-
---------
1728-
+00:30
1725+
SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM";
1726+
OF | TZH:TZM
1727+
--------+---------
1728+
+00:30 | +00:30
17291729
(1 row)
17301730

17311731
SET timezone = '00:30';
1732-
SELECT to_char(now(), 'OF');
1733-
to_char
1734-
---------
1735-
-00:30
1732+
SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM";
1733+
OF | TZH:TZM
1734+
--------+---------
1735+
-00:30 | -00:30
17361736
(1 row)
17371737

17381738
SET timezone = '-04:30';
1739-
SELECT to_char(now(), 'OF');
1740-
to_char
1741-
---------
1742-
+04:30
1739+
SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM";
1740+
OF | TZH:TZM
1741+
--------+---------
1742+
+04:30 | +04:30
17431743
(1 row)
17441744

17451745
SET timezone = '04:30';
1746-
SELECT to_char(now(), 'OF');
1747-
to_char
1748-
---------
1749-
-04:30
1746+
SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM";
1747+
OF | TZH:TZM
1748+
--------+---------
1749+
-04:30 | -04:30
1750+
(1 row)
1751+
1752+
SET timezone = '-04:15';
1753+
SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM";
1754+
OF | TZH:TZM
1755+
--------+---------
1756+
+04:15 | +04:15
1757+
(1 row)
1758+
1759+
SET timezone = '04:15';
1760+
SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM";
1761+
OF | TZH:TZM
1762+
--------+---------
1763+
-04:15 | -04:15
17501764
(1 row)
17511765

17521766
RESET timezone;

‎src/test/regress/sql/horology.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,12 @@ SELECT to_timestamp(' 20050302', 'YYYYMMDD');
446446
SELECT to_timestamp('2011-12-18 11:38 AM','YYYY-MM-DD HH12:MI PM');
447447
SELECT to_timestamp('2011-12-18 11:38 PM','YYYY-MM-DD HH12:MI PM');
448448

449+
SELECT to_timestamp('2011-12-18 11:38 +05','YYYY-MM-DD HH12:MI TZH');
450+
SELECT to_timestamp('2011-12-18 11:38 -05','YYYY-MM-DD HH12:MI TZH');
451+
SELECT to_timestamp('2011-12-18 11:38 +05:20','YYYY-MM-DD HH12:MI TZH:TZM');
452+
SELECT to_timestamp('2011-12-18 11:38 -05:20','YYYY-MM-DD HH12:MI TZH:TZM');
453+
SELECT to_timestamp('2011-12-18 11:38 20','YYYY-MM-DD HH12:MI TZM');
454+
449455
--
450456
-- Check handling of multiple spaces in format and/or input
451457
--

‎src/test/regress/sql/timestamptz.sql

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,21 +248,25 @@ SELECT '' AS to_char_10, to_char(d1, 'IYYY IYY IY I IW IDDD ID')
248248
SELECT''AS to_char_11, to_char(d1,'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID')
249249
FROM TIMESTAMPTZ_TBL;
250250

251-
-- Check OF with various zone offsets, particularly fractional hours
251+
-- Check OF, TZH, TZM with various zone offsets, particularly fractional hours
252252
SET timezone='00:00';
253-
SELECT to_char(now(),'OF');
253+
SELECT to_char(now(),'OF')as"OF", to_char(now(),'TZH:TZM')as"TZH:TZM";
254254
SET timezone='+02:00';
255-
SELECT to_char(now(),'OF');
255+
SELECT to_char(now(),'OF')as"OF", to_char(now(),'TZH:TZM')as"TZH:TZM";
256256
SET timezone='-13:00';
257-
SELECT to_char(now(),'OF');
257+
SELECT to_char(now(),'OF')as"OF", to_char(now(),'TZH:TZM')as"TZH:TZM";
258258
SET timezone='-00:30';
259-
SELECT to_char(now(),'OF');
259+
SELECT to_char(now(),'OF')as"OF", to_char(now(),'TZH:TZM')as"TZH:TZM";
260260
SET timezone='00:30';
261-
SELECT to_char(now(),'OF');
261+
SELECT to_char(now(),'OF')as"OF", to_char(now(),'TZH:TZM')as"TZH:TZM";
262262
SET timezone='-04:30';
263-
SELECT to_char(now(),'OF');
263+
SELECT to_char(now(),'OF')as"OF", to_char(now(),'TZH:TZM')as"TZH:TZM";
264264
SET timezone='04:30';
265-
SELECT to_char(now(),'OF');
265+
SELECT to_char(now(),'OF')as"OF", to_char(now(),'TZH:TZM')as"TZH:TZM";
266+
SET timezone='-04:15';
267+
SELECT to_char(now(),'OF')as"OF", to_char(now(),'TZH:TZM')as"TZH:TZM";
268+
SET timezone='04:15';
269+
SELECT to_char(now(),'OF')as"OF", to_char(now(),'TZH:TZM')as"TZH:TZM";
266270
RESET timezone;
267271

268272
CREATETABLETIMESTAMPTZ_TST (aint , btimestamptz);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp