Fix wrong week returnded by date_trunc('week') for early dates in
January --- would return wrong year for 2005-01-01 and 2006-01-01. per report from Robert Creager. Backpatch to 8.0.X.
This commit is contained in:
parent
a70574d803
commit
9e9724e8bd
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.243 2005/03/30 04:52:49 neilc Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.244 2005/04/01 14:25:22 momjian Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -5472,6 +5472,12 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');
|
|||||||
week starts on Monday.) In other words, the first Thursday of
|
week starts on Monday.) In other words, the first Thursday of
|
||||||
a year is in week 1 of that year. (for <type>timestamp</type> values only)
|
a year is in week 1 of that year. (for <type>timestamp</type> values only)
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
Because of this, it is possible for early January dates to be part of the
|
||||||
|
52nd or 53rd week of the previous year. For example, <literal>2005-01-01</>
|
||||||
|
is part of the 53rd week of year 2004, and <literal>2006-01-01</> is part of
|
||||||
|
the 52nd week of year 2005.
|
||||||
|
</para>
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');
|
SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.117 2004/12/31 22:01:22 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.118 2005/04/01 14:25:23 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2754,12 +2754,23 @@ timestamp_trunc(PG_FUNCTION_ARGS)
|
|||||||
switch (val)
|
switch (val)
|
||||||
{
|
{
|
||||||
case DTK_WEEK:
|
case DTK_WEEK:
|
||||||
isoweek2date(date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
{
|
||||||
|
int woy;
|
||||||
|
|
||||||
|
woy = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
|
||||||
|
/*
|
||||||
|
* If it is week 52/53 and the month is January,
|
||||||
|
* then the week must belong to the previous year.
|
||||||
|
*/
|
||||||
|
if (woy >= 52 && tm->tm_mon == 1)
|
||||||
|
--tm->tm_year;
|
||||||
|
isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
||||||
tm->tm_hour = 0;
|
tm->tm_hour = 0;
|
||||||
tm->tm_min = 0;
|
tm->tm_min = 0;
|
||||||
tm->tm_sec = 0;
|
tm->tm_sec = 0;
|
||||||
fsec = 0;
|
fsec = 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case DTK_MILLENNIUM:
|
case DTK_MILLENNIUM:
|
||||||
/* see comments in timestamptz_trunc */
|
/* see comments in timestamptz_trunc */
|
||||||
if (tm->tm_year > 0)
|
if (tm->tm_year > 0)
|
||||||
@ -2874,13 +2885,24 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
|
|||||||
switch (val)
|
switch (val)
|
||||||
{
|
{
|
||||||
case DTK_WEEK:
|
case DTK_WEEK:
|
||||||
isoweek2date(date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
{
|
||||||
|
int woy;
|
||||||
|
|
||||||
|
woy = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
|
||||||
|
/*
|
||||||
|
* If it is week 52/53 and the month is January,
|
||||||
|
* then the week must belong to the previous year.
|
||||||
|
*/
|
||||||
|
if (woy >= 52 && tm->tm_mon == 1)
|
||||||
|
--tm->tm_year;
|
||||||
|
isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
||||||
tm->tm_hour = 0;
|
tm->tm_hour = 0;
|
||||||
tm->tm_min = 0;
|
tm->tm_min = 0;
|
||||||
tm->tm_sec = 0;
|
tm->tm_sec = 0;
|
||||||
fsec = 0;
|
fsec = 0;
|
||||||
redotz = true;
|
redotz = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
/* one may consider DTK_THOUSAND and DTK_HUNDRED... */
|
/* one may consider DTK_THOUSAND and DTK_HUNDRED... */
|
||||||
case DTK_MILLENNIUM:
|
case DTK_MILLENNIUM:
|
||||||
|
|
||||||
@ -3142,7 +3164,7 @@ date2isoweek(int year, int mon, int mday)
|
|||||||
* Sometimes the last few days in a year will fall into the first week
|
* Sometimes the last few days in a year will fall into the first week
|
||||||
* of the next year, so check for this.
|
* of the next year, so check for this.
|
||||||
*/
|
*/
|
||||||
if (result >= 53)
|
if (result >= 52)
|
||||||
{
|
{
|
||||||
day4 = date2j(year + 1, 1, 4);
|
day4 = date2j(year + 1, 1, 4);
|
||||||
|
|
||||||
@ -3198,7 +3220,7 @@ date2isoyear(int year, int mon, int mday)
|
|||||||
* Sometimes the last few days in a year will fall into the first week
|
* Sometimes the last few days in a year will fall into the first week
|
||||||
* of the next year, so check for this.
|
* of the next year, so check for this.
|
||||||
*/
|
*/
|
||||||
if (result >= 53)
|
if (result >= 52)
|
||||||
{
|
{
|
||||||
day4 = date2j(year + 1, 1, 4);
|
day4 = date2j(year + 1, 1, 4);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user