aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2024-01-20 00:31:44 +0000
committerdrh <>2024-01-20 00:31:44 +0000
commitf08287cc1243ff220d2a7f001809b37752b1bcd6 (patch)
tree2e8c42f9170524ac692d84ab950b72bf9a1354fe /src
parenta4802720a1fe1d51c4e35a2e85c8c09ade420a93 (diff)
downloadsqlite-f08287cc1243ff220d2a7f001809b37752b1bcd6.tar.gz
sqlite-f08287cc1243ff220d2a7f001809b37752b1bcd6.zip
Implement a new algorithm for computing ISO week values in strftime() based
on the idea (from [forum/forumpost/3681cb1bcd|Nuno Cruces]) of shifting the date being tested to the Thursday of the same week. FossilOrigin-Name: b06ab46a9ee98719159ed3e05cdfbf26281353d781206f56ed7cb12859210fed
Diffstat (limited to 'src')
-rw-r--r--src/date.c61
1 files changed, 16 insertions, 45 deletions
diff --git a/src/date.c b/src/date.c
index 059d4c88a..76e1894f8 100644
--- a/src/date.c
+++ b/src/date.c
@@ -1249,7 +1249,7 @@ static int dayOfYear(DateTime *pDate){
jan01.M = 1;
jan01.D = 1;
computeJD(&jan01);
- return (int)((pDate->iJD-jan01.iJD+45300000)/86400000) + 1;
+ return (int)((pDate->iJD-jan01.iJD+43200000)/86400000) + 1;
}
/*
@@ -1264,41 +1264,6 @@ static int dayOfWeek(DateTime *pDate){
}
/*
-** Compute the day-of-week (0=Sunday, 1=Monday, ..., 6=Saturday) for
-** the last day of the calendar year Y.
-*/
-static int lastDayOfYear(int Y){
- return (Y + (Y/4) - (Y/100) + (Y/400))%7;
-}
-
-/*
-** Return the number of ISO weeks in calendar year Y. The answer is
-** either 52 or 53.
-*/
-static int weeksInYear(int Y){
- if( lastDayOfYear(Y)==4 || lastDayOfYear(Y-1)==3 ){
- return 53;
- }else{
- return 52;
- }
-}
-
-/*
-** Compute the number days since the start of the ISO-week year for pDate.
-** The ISO-week year starts on the first day of the week (always a Monday)
-** that contains the first Thursday on or after January 1.
-*/
-static int isoWeekNumber(DateTime *pDate){
- int wn = (10 + dayOfYear(pDate) - dayOfWeek(pDate))/7;
- if( wn<1 ){
- wn = weeksInYear(pDate->Y-1);
- }else if( wn>weeksInYear(pDate->Y) ){
- wn = 1;
- }
- return wn;
-}
-
-/*
** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
**
** Return a string described by FORMAT. Conversions as follows:
@@ -1376,16 +1341,16 @@ static void strftimeFunc(
}
case 'G': /* Fall thru */
case 'g': {
- int Y = x.Y;
- if( x.M==12 && isoWeekNumber(&x)==1 ){
- Y++;
- }else if( x.M==1 && isoWeekNumber(&x)>=52 ){
- Y--;
- }
+ DateTime y = x;
+ assert( y.validJD );
+ /* Move y so that it is the Thursday in the same week as x */
+ y.iJD += (4 - dayOfWeek(&x))*86400000;
+ y.validYMD = 0;
+ computeYMD(&y);
if( cf=='g' ){
- sqlite3_str_appendf(&sRes, "%02d", Y%100);
+ sqlite3_str_appendf(&sRes, "%02d", y.Y%100);
}else{
- sqlite3_str_appendf(&sRes, "%04d", Y);
+ sqlite3_str_appendf(&sRes, "%04d", y.Y);
}
break;
}
@@ -1466,7 +1431,13 @@ static void strftimeFunc(
break;
}
case 'V': { /* Week num. 01-53. First week with a Thur is week 01 */
- sqlite3_str_appendf(&sRes,"%02d", isoWeekNumber(&x));
+ DateTime y = x;
+ /* Adjust y so that is the Thursday in the same week as x */
+ assert( y.validJD );
+ y.iJD += (4 - dayOfWeek(&x))*86400000;
+ y.validYMD = 0;
+ computeYMD(&y);
+ sqlite3_str_appendf(&sRes,"%02d", (dayOfYear(&y)-1)/7+1);
break;
}
case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */