Skip to content

Commit 015722f

Browse files
committed
Fix to_date() and to_timestamp() to allow specification of the day of
the week via ISO or Gregorian designations. The fix is to store the day-of-week consistently as 1-7, Sunday = 1. Fixes bug reported by Marc Munro
1 parent e442b0f commit 015722f

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

src/backend/utils/adt/formatting.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ typedef struct
412412
mi,
413413
ss,
414414
ssss,
415-
d,
415+
d, /* stored as 1-7, Sunday = 1, 0 means missing */
416416
dd,
417417
ddd,
418418
mm,
@@ -2897,13 +2897,15 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
28972897
from_char_seq_search(&value, &s, days, ONE_UPPER,
28982898
MAX_DAY_LEN, n);
28992899
from_char_set_int(&out->d, value, n);
2900+
out->d++;
29002901
break;
29012902
case DCH_DY:
29022903
case DCH_Dy:
29032904
case DCH_dy:
29042905
from_char_seq_search(&value, &s, days, ONE_UPPER,
29052906
MAX_DY_LEN, n);
29062907
from_char_set_int(&out->d, value, n);
2908+
out->d++;
29072909
break;
29082910
case DCH_DDD:
29092911
from_char_parse_int(&out->ddd, &s, n);
@@ -2919,11 +2921,13 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
29192921
break;
29202922
case DCH_D:
29212923
from_char_parse_int(&out->d, &s, n);
2922-
out->d--;
29232924
s += SKIP_THth(n->suffix);
29242925
break;
29252926
case DCH_ID:
29262927
from_char_parse_int_len(&out->d, &s, 1, n);
2928+
/* Shift numbering to match Gregorian where Sunday = 1 */
2929+
if (++out->d > 7)
2930+
out->d = 1;
29272931
s += SKIP_THth(n->suffix);
29282932
break;
29292933
case DCH_WW:
@@ -3534,7 +3538,7 @@ do_to_timestamp(text *date_txt, text *fmt,
35343538
if (tmfc.w)
35353539
tmfc.dd = (tmfc.w - 1) * 7 + 1;
35363540
if (tmfc.d)
3537-
tm->tm_wday = tmfc.d;
3541+
tm->tm_wday = tmfc.d - 1; /* convert to native numbering */
35383542
if (tmfc.dd)
35393543
tm->tm_mday = tmfc.dd;
35403544
if (tmfc.ddd)

src/backend/utils/adt/timestamp.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3775,18 +3775,22 @@ isoweek2date(int woy, int *year, int *mon, int *mday)
37753775

37763776
/* isoweekdate2date()
37773777
*
3778-
* Convert an ISO 8601 week date (ISO year, ISO week and day of week) into a Gregorian date.
3778+
* Convert an ISO 8601 week date (ISO year, ISO week) into a Gregorian date.
3779+
* Gregorian day of week sent so weekday strings can be supplied.
37793780
* Populates year, mon, and mday with the correct Gregorian values.
37803781
* year must be passed in as the ISO year.
37813782
*/
37823783
void
3783-
isoweekdate2date(int isoweek, int isowday, int *year, int *mon, int *mday)
3784+
isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday)
37843785
{
37853786
int jday;
37863787

37873788
jday = isoweek2j(*year, isoweek);
3788-
jday += isowday - 1;
3789-
3789+
/* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
3790+
if (wday > 1)
3791+
jday += wday - 2;
3792+
else
3793+
jday += 6;
37903794
j2date(jday, year, mon, mday);
37913795
}
37923796

src/include/utils/timestamp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ extern int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2);
236236

237237
extern int isoweek2j(int year, int week);
238238
extern void isoweek2date(int woy, int *year, int *mon, int *mday);
239-
extern void isoweekdate2date(int isoweek, int isowday, int *year, int *mon, int *mday);
239+
extern void isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday);
240240
extern int date2isoweek(int year, int mon, int mday);
241241
extern int date2isoyear(int year, int mon, int mday);
242242
extern int date2isoyearday(int year, int mon, int mday);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy