Fix (well, add) support for ISO "week" in date_part(). Needed for ODBC.
authorThomas G. Lockhart <lockhart@fourpalms.org>
Fri, 14 Apr 2000 15:22:10 +0000 (15:22 +0000)
committerThomas G. Lockhart <lockhart@fourpalms.org>
Fri, 14 Apr 2000 15:22:10 +0000 (15:22 +0000)
Fix spelling of "millennium".
 Thanks to Mika Nystrom <mika@camembert.cs.caltech.edu> for spotting this.

src/backend/utils/adt/datetime.c
src/backend/utils/adt/timestamp.c

index 2f899d21e931e3388b80c6c0423006979dad3cf2..f252a42ddc5184ab766fcb01f87b9b164f5e6226 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.46 2000/04/12 17:15:49 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.47 2000/04/14 15:22:10 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -260,15 +260,14 @@ static datetkn deltatktbl[] = {
    {"hours", UNITS, DTK_HOUR}, /* "hours" relative time units */
    {"hr", UNITS, DTK_HOUR},    /* "hour" relative time units */
    {"hrs", UNITS, DTK_HOUR},   /* "hours" relative time units */
-   {INVALID, RESERV, DTK_INVALID},     /* "invalid" reserved for invalid
-                                        * time */
+   {INVALID, RESERV, DTK_INVALID},     /* reserved for invalid time */
    {"m", UNITS, DTK_MINUTE},   /* "minute" relative time units */
    {"microsecon", UNITS, DTK_MICROSEC},        /* "microsecond" relative
                                                 * time units */
-   {"mil", UNITS, DTK_MILLENIUM},      /* "millenium" relative time units */
-   {"mils", UNITS, DTK_MILLENIUM},     /* "millenia" relative time units */
-   {"millenia", UNITS, DTK_MILLENIUM}, /* "millenia" relative time units */
-   {DMILLENIUM, UNITS, DTK_MILLENIUM}, /* "millenium" relative time units */
+   {"mil", UNITS, DTK_MILLENNIUM},     /* "millennium" relative time units */
+   {"mils", UNITS, DTK_MILLENNIUM},      /* "millennia" relative time units */
+   {"millennia", UNITS, DTK_MILLENNIUM}, /* "millennia" relative time units */
+   {DMILLENNIUM, UNITS, DTK_MILLENNIUM}, /* "millennium" relative time units */
    {"millisecon", UNITS, DTK_MILLISEC},        /* relative time units */
    {"min", UNITS, DTK_MINUTE}, /* "minute" relative time units */
    {"mins", UNITS, DTK_MINUTE},/* "minutes" relative time units */
@@ -1794,7 +1793,7 @@ DecodeDateDelta(char **field, int *ftype, int nf, int *dtype, struct tm * tm, do
                        tmask = ((fmask & DTK_M(YEAR)) ? 0 : DTK_M(YEAR));
                        break;
 
-                   case DTK_MILLENIUM:
+                   case DTK_MILLENNIUM:
                        tm->tm_year += val * 1000;
                        if (fval != 0)
                            tm->tm_mon += (fval * 12000);
index a731ce3cef55c1393ff4eb2e6ca128ffd02ccb1d..56ab2f10bb678f68424f1b7e45535d298d9705c0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.25 2000/04/12 17:15:51 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.26 2000/04/14 15:22:10 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1621,7 +1621,7 @@ timestamp_trunc(text *units, Timestamp *timestamp)
        {
            switch (val)
            {
-               case DTK_MILLENIUM:
+               case DTK_MILLENNIUM:
                    tm->tm_year = (tm->tm_year / 1000) * 1000;
                case DTK_CENTURY:
                    tm->tm_year = (tm->tm_year / 100) * 100;
@@ -1759,7 +1759,7 @@ interval_trunc(text *units, Interval *interval)
        {
            switch (val)
            {
-               case DTK_MILLENIUM:
+               case DTK_MILLENNIUM:
                    tm->tm_year = (tm->tm_year / 1000) * 1000;
                case DTK_CENTURY:
                    tm->tm_year = (tm->tm_year / 100) * 100;
@@ -1927,6 +1927,38 @@ timestamp_part(text *units, Timestamp *timestamp)
                    *result = (tm->tm_mon / 4) + 1;
                    break;
 
+               case DTK_WEEK:
+                   {
+                       int day0, day4, dayn;
+                       dayn = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
+                       day4 = date2j(tm->tm_year, 1, 4);
+                       /* day0 == offset to first day of week (Monday) */
+                       day0 = (j2day(day4 - 1) % 7);
+                       /* We need the first week containing a Thursday,
+                        * otherwise this day falls into the previous year
+                        * for purposes of counting weeks
+                        */
+                       if (dayn < (day4 - day0))
+                       {
+                           day4 = date2j((tm->tm_year - 1), 1, 4);
+                           /* day0 == offset to first day of week (Monday) */
+                           day0 = (j2day(day4 - 1) % 7);
+                       }
+                       *result = (((dayn - (day4 - day0)) / 7) + 1);
+                       /* Sometimes the last few days in a year will fall into
+                        * the first week of the next year, so check for this.
+                        */
+                       if (*result >= 53)
+                       {
+                           day4 = date2j((tm->tm_year + 1), 1, 4);
+                           /* day0 == offset to first day of week (Monday) */
+                           day0 = (j2day(day4 - 1) % 7);
+                           if (dayn >= (day4 - day0))
+                               *result = (((dayn - (day4 - day0)) / 7) + 1);
+                       }
+                   }
+                   break;
+
                case DTK_YEAR:
                    *result = tm->tm_year;
                    break;
@@ -1939,7 +1971,7 @@ timestamp_part(text *units, Timestamp *timestamp)
                    *result = (tm->tm_year / 100);
                    break;
 
-               case DTK_MILLENIUM:
+               case DTK_MILLENNIUM:
                    *result = (tm->tm_year / 1000);
                    break;
 
@@ -2082,7 +2114,7 @@ interval_part(text *units, Interval *interval)
                    *result = (tm->tm_year / 100);
                    break;
 
-               case DTK_MILLENIUM:
+               case DTK_MILLENNIUM:
                    *result = (tm->tm_year / 1000);
                    break;