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
This commit is contained in:
parent
e442b0f0c6
commit
015722fb36
@ -412,7 +412,7 @@ typedef struct
|
|||||||
mi,
|
mi,
|
||||||
ss,
|
ss,
|
||||||
ssss,
|
ssss,
|
||||||
d,
|
d, /* stored as 1-7, Sunday = 1, 0 means missing */
|
||||||
dd,
|
dd,
|
||||||
ddd,
|
ddd,
|
||||||
mm,
|
mm,
|
||||||
@ -2897,6 +2897,7 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
|
|||||||
from_char_seq_search(&value, &s, days, ONE_UPPER,
|
from_char_seq_search(&value, &s, days, ONE_UPPER,
|
||||||
MAX_DAY_LEN, n);
|
MAX_DAY_LEN, n);
|
||||||
from_char_set_int(&out->d, value, n);
|
from_char_set_int(&out->d, value, n);
|
||||||
|
out->d++;
|
||||||
break;
|
break;
|
||||||
case DCH_DY:
|
case DCH_DY:
|
||||||
case DCH_Dy:
|
case DCH_Dy:
|
||||||
@ -2904,6 +2905,7 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
|
|||||||
from_char_seq_search(&value, &s, days, ONE_UPPER,
|
from_char_seq_search(&value, &s, days, ONE_UPPER,
|
||||||
MAX_DY_LEN, n);
|
MAX_DY_LEN, n);
|
||||||
from_char_set_int(&out->d, value, n);
|
from_char_set_int(&out->d, value, n);
|
||||||
|
out->d++;
|
||||||
break;
|
break;
|
||||||
case DCH_DDD:
|
case DCH_DDD:
|
||||||
from_char_parse_int(&out->ddd, &s, n);
|
from_char_parse_int(&out->ddd, &s, n);
|
||||||
@ -2919,11 +2921,13 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
|
|||||||
break;
|
break;
|
||||||
case DCH_D:
|
case DCH_D:
|
||||||
from_char_parse_int(&out->d, &s, n);
|
from_char_parse_int(&out->d, &s, n);
|
||||||
out->d--;
|
|
||||||
s += SKIP_THth(n->suffix);
|
s += SKIP_THth(n->suffix);
|
||||||
break;
|
break;
|
||||||
case DCH_ID:
|
case DCH_ID:
|
||||||
from_char_parse_int_len(&out->d, &s, 1, n);
|
from_char_parse_int_len(&out->d, &s, 1, n);
|
||||||
|
/* Shift numbering to match Gregorian where Sunday = 1 */
|
||||||
|
if (++out->d > 7)
|
||||||
|
out->d = 1;
|
||||||
s += SKIP_THth(n->suffix);
|
s += SKIP_THth(n->suffix);
|
||||||
break;
|
break;
|
||||||
case DCH_WW:
|
case DCH_WW:
|
||||||
@ -3534,7 +3538,7 @@ do_to_timestamp(text *date_txt, text *fmt,
|
|||||||
if (tmfc.w)
|
if (tmfc.w)
|
||||||
tmfc.dd = (tmfc.w - 1) * 7 + 1;
|
tmfc.dd = (tmfc.w - 1) * 7 + 1;
|
||||||
if (tmfc.d)
|
if (tmfc.d)
|
||||||
tm->tm_wday = tmfc.d;
|
tm->tm_wday = tmfc.d - 1; /* convert to native numbering */
|
||||||
if (tmfc.dd)
|
if (tmfc.dd)
|
||||||
tm->tm_mday = tmfc.dd;
|
tm->tm_mday = tmfc.dd;
|
||||||
if (tmfc.ddd)
|
if (tmfc.ddd)
|
||||||
|
@ -3775,18 +3775,22 @@ isoweek2date(int woy, int *year, int *mon, int *mday)
|
|||||||
|
|
||||||
/* isoweekdate2date()
|
/* isoweekdate2date()
|
||||||
*
|
*
|
||||||
* Convert an ISO 8601 week date (ISO year, ISO week and day of week) into a Gregorian date.
|
* Convert an ISO 8601 week date (ISO year, ISO week) into a Gregorian date.
|
||||||
|
* Gregorian day of week sent so weekday strings can be supplied.
|
||||||
* Populates year, mon, and mday with the correct Gregorian values.
|
* Populates year, mon, and mday with the correct Gregorian values.
|
||||||
* year must be passed in as the ISO year.
|
* year must be passed in as the ISO year.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
isoweekdate2date(int isoweek, int isowday, int *year, int *mon, int *mday)
|
isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday)
|
||||||
{
|
{
|
||||||
int jday;
|
int jday;
|
||||||
|
|
||||||
jday = isoweek2j(*year, isoweek);
|
jday = isoweek2j(*year, isoweek);
|
||||||
jday += isowday - 1;
|
/* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
|
||||||
|
if (wday > 1)
|
||||||
|
jday += wday - 2;
|
||||||
|
else
|
||||||
|
jday += 6;
|
||||||
j2date(jday, year, mon, mday);
|
j2date(jday, year, mon, mday);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ extern int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2);
|
|||||||
|
|
||||||
extern int isoweek2j(int year, int week);
|
extern int isoweek2j(int year, int week);
|
||||||
extern void isoweek2date(int woy, int *year, int *mon, int *mday);
|
extern void isoweek2date(int woy, int *year, int *mon, int *mday);
|
||||||
extern void isoweekdate2date(int isoweek, int isowday, int *year, int *mon, int *mday);
|
extern void isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday);
|
||||||
extern int date2isoweek(int year, int mon, int mday);
|
extern int date2isoweek(int year, int mon, int mday);
|
||||||
extern int date2isoyear(int year, int mon, int mday);
|
extern int date2isoyear(int year, int mon, int mday);
|
||||||
extern int date2isoyearday(int year, int mon, int mday);
|
extern int date2isoyearday(int year, int mon, int mday);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user