]> granicus.if.org Git - postgresql/commitdiff
Add timezone offset output option to to_char()
authorBruce Momjian <bruce@momjian.us>
Mon, 1 Jul 2013 17:40:18 +0000 (13:40 -0400)
committerBruce Momjian <bruce@momjian.us>
Mon, 1 Jul 2013 17:40:32 +0000 (13:40 -0400)
Add ability for to_char() to output the timezone's UTC offset (OF).  We
already have the ability to return the timezone abbeviation (TZ/tz).
Per request from Andrew Dunstan

doc/src/sgml/func.sgml
src/backend/utils/adt/formatting.c

index 7c009d899cc24fa7f4acc0729f6bf57f6eb251f5..5765ddf576ec0d955c8b9148186a2aee4648f2b5 100644 (file)
@@ -5645,6 +5645,10 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
         <entry><literal>tz</literal></entry>
         <entry>lower case time-zone name</entry>
        </row>
+       <row>
+        <entry><literal>OF</literal></entry>
+        <entry>time-zone offset</entry>
+       </row>
       </tbody>
      </tgroup>
     </table>
index 7b854062f0dbcd5b5bb90725ba39daa7ec2d19f7..36353c39c16dab0254101cb9a840307d5d4751f1 100644 (file)
@@ -600,6 +600,7 @@ typedef enum
        DCH_MS,
        DCH_Month,
        DCH_Mon,
+       DCH_OF,
        DCH_P_M,
        DCH_PM,
        DCH_Q,
@@ -746,6 +747,7 @@ static const KeyWord DCH_keywords[] = {
        {"MS", 2, DCH_MS, TRUE, FROM_CHAR_DATE_NONE},
        {"Month", 5, DCH_Month, FALSE, FROM_CHAR_DATE_GREGORIAN},
        {"Mon", 3, DCH_Mon, FALSE, FROM_CHAR_DATE_GREGORIAN},
+       {"OF", 2, DCH_OF, FALSE, FROM_CHAR_DATE_NONE},          /* O */
        {"P.M.", 4, DCH_P_M, FALSE, FROM_CHAR_DATE_NONE},       /* P */
        {"PM", 2, DCH_PM, FALSE, FROM_CHAR_DATE_NONE},
        {"Q", 1, DCH_Q, TRUE, FROM_CHAR_DATE_NONE}, /* Q */
@@ -874,7 +876,7 @@ static const int DCH_index[KeyWord_INDEX_SIZE] = {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, DCH_A_D, DCH_B_C, DCH_CC, DCH_DAY, -1,
-       DCH_FX, -1, DCH_HH24, DCH_IDDD, DCH_J, -1, -1, DCH_MI, -1, -1,
+       DCH_FX, -1, DCH_HH24, DCH_IDDD, DCH_J, -1, -1, DCH_MI, -1, DCH_OF,
        DCH_P_M, DCH_Q, DCH_RM, DCH_SSSS, DCH_TZ, DCH_US, -1, DCH_WW, -1, DCH_Y_YYY,
        -1, -1, -1, -1, -1, -1, -1, DCH_a_d, DCH_b_c, DCH_cc,
        DCH_day, -1, DCH_fx, -1, DCH_hh24, DCH_iddd, DCH_j, -1, -1, DCH_mi,
@@ -2502,6 +2504,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
                                        s += strlen(s);
                                }
                                break;
+                       case DCH_OF:
+                               INVALID_FOR_INTERVAL;
+                               sprintf(s, "%+0*ld", S_FM(n->suffix) ? 0 : 3, tm->tm_gmtoff / SECS_PER_HOUR);
+                               s += strlen(s);
+                               if (tm->tm_gmtoff % SECS_PER_HOUR != 0)
+                               {
+                                       sprintf(s, ":%02ld", (tm->tm_gmtoff % SECS_PER_HOUR) / SECS_PER_MINUTE);
+                                       s += strlen(s);
+                               }
+                               break;
                        case DCH_A_D:
                        case DCH_B_C:
                                INVALID_FOR_INTERVAL;
@@ -2915,9 +2927,10 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
                                break;
                        case DCH_tz:
                        case DCH_TZ:
+                       case DCH_OF:
                                ereport(ERROR,
                                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                errmsg("\"TZ\"/\"tz\" format patterns are not supported in to_date")));
+                                                errmsg("\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date")));
                        case DCH_A_D:
                        case DCH_B_C:
                        case DCH_a_d: