From 3e803f72732f591a7913f5be212012ea1193705c Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 19 Feb 2007 17:41:39 +0000 Subject: [PATCH] Add "isodow" option to EXTRACT() and date_part() where Sunday = 7. --- doc/src/sgml/func.sgml | 35 +++++++++++++++++----- src/backend/utils/adt/datetime.c | 3 +- src/backend/utils/adt/timestamp.c | 8 ++++- src/include/utils/datetime.h | 3 +- src/interfaces/ecpg/pgtypeslib/dt.h | 3 +- src/interfaces/ecpg/pgtypeslib/dt_common.c | 3 +- 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 4a44e669b1..ac7a0d1638 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -1,4 +1,4 @@ - + Functions and Operators @@ -5732,8 +5732,8 @@ SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40'); dow - The day of the week (0 - 6; Sunday is 0) (for - timestamp values only) + The day of the week as Sunday(0) to + Saturday(6) @@ -5741,7 +5741,7 @@ SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); Result: 5 - Note that extract's day of the week numbering is + Note that extract's day of the week numbering is different from that of the to_char function. @@ -5752,7 +5752,7 @@ SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); doy - The day of the year (1 - 365/366) (for timestamp values only) + The day of the year (1 - 365/366) @@ -5805,6 +5805,26 @@ SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40'); + + isodow + + + The day of the week as Monday(1) to + Sunday(7) + + + +SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40'); +Result: 7 + + + This is identical to dow except for Sunday. This + matches the ISO 8601 day of the week numbering. + + + + + isoyear @@ -5923,8 +5943,7 @@ SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); quarter - The quarter of the year (1 - 4) that the day is in (for - timestamp values only) + The quarter of the year (1 - 4) that the day is in @@ -5989,7 +6008,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); (ISO 8601), the first week of a year contains January 4 of that year. (The ISO-8601 week starts on Monday.) In other words, the first Thursday of - a year is in week 1 of that year. (for timestamp values only) + a year is in week 1 of that year. Because of this, it is possible for early January dates to be part of the diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 18226b5508..6154c96b9c 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.176 2007/02/16 03:39:45 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.177 2007/02/19 17:41:39 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -125,6 +125,7 @@ static const datetkn datetktbl[] = { {"h", UNITS, DTK_HOUR}, /* "hour" */ {LATE, RESERV, DTK_LATE}, /* "infinity" reserved for "late time" */ {INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for bad time */ + {"isodow", RESERV, DTK_ISODOW}, /* ISO day of week, Sunday == 7 */ {"isoyear", UNITS, DTK_ISOYEAR}, /* year in terms of the ISO week date */ {"j", UNITS, DTK_JULIAN}, {"jan", MONTH, 1}, diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 7632e1b896..a842c1b02c 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.172 2007/02/16 03:39:45 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.173 2007/02/19 17:41:39 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -4112,11 +4112,14 @@ timestamp_part(PG_FUNCTION_ARGS) break; } case DTK_DOW: + case DTK_ISODOW: if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); + if (val == DTK_ISODOW && result == 0) + result = 7; break; case DTK_DOY: @@ -4322,11 +4325,14 @@ timestamptz_part(PG_FUNCTION_ARGS) break; case DTK_DOW: + case DTK_ISODOW: if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); + if (val == DTK_ISODOW && result == 0) + result = 7; break; case DTK_DOY: diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h index fc7b16fdb4..df6cf5e4f3 100644 --- a/src/include/utils/datetime.h +++ b/src/include/utils/datetime.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.64 2007/02/16 03:39:45 momjian Exp $ + * $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.65 2007/02/19 17:41:39 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -166,6 +166,7 @@ #define DTK_TZ_HOUR 34 #define DTK_TZ_MINUTE 35 #define DTK_ISOYEAR 36 +#define DTK_ISODOW 37 /* diff --git a/src/interfaces/ecpg/pgtypeslib/dt.h b/src/interfaces/ecpg/pgtypeslib/dt.h index d0bfc00bbd..b94bd5a73b 100644 --- a/src/interfaces/ecpg/pgtypeslib/dt.h +++ b/src/interfaces/ecpg/pgtypeslib/dt.h @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt.h,v 1.35 2007/02/16 03:39:45 momjian Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt.h,v 1.36 2007/02/19 17:41:39 momjian Exp $ */ #ifndef DT_H #define DT_H @@ -158,6 +158,7 @@ typedef double fsec_t; #define DTK_TZ_HOUR 34 #define DTK_TZ_MINUTE 35 #define DTK_ISOYEAR 36 +#define DTK_ISODOW 37 /* diff --git a/src/interfaces/ecpg/pgtypeslib/dt_common.c b/src/interfaces/ecpg/pgtypeslib/dt_common.c index d6ccf3310d..8fb0818add 100644 --- a/src/interfaces/ecpg/pgtypeslib/dt_common.c +++ b/src/interfaces/ecpg/pgtypeslib/dt_common.c @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt_common.c,v 1.36 2006/09/26 07:56:56 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt_common.c,v 1.37 2007/02/19 17:41:39 momjian Exp $ */ #include "postgres_fe.h" @@ -214,6 +214,7 @@ static datetkn datetktbl[] = { {"irkst", DTZ, POS(36)}, /* Irkutsk Summer Time */ {"irkt", TZ, POS(32)}, /* Irkutsk Time */ {"irt", TZ, POS(14)}, /* Iran Time */ + {"isodow", RESERV, DTK_ISODOW}, /* ISO day of week, Sunday == 7 */ #if 0 isst #endif