From 0cbc2143b9d09f7d4168dac79dc944afabfcae92 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 29 May 2023 18:01:42 +0000 Subject: [PATCH 1/7] Prototype implementation of a proposed "timediff(X,Y)" SQL function. FossilOrigin-Name: 054a195125a273bab026ada5f07cc7c32818007027a1fd028ca59d2f179276d4 --- manifest | 15 +++++---- manifest.uuid | 2 +- src/date.c | 90 +++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 87 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 59a53cb9fb..7bca2b96d2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sissue\swith\ssqldiff\sreported\sby\n[forum:/info/9bd2155bdfae25a7|forum\spost\s9bd2155bdfae25a7]. -D 2023-05-27T20:08:23.912 +C Prototype\simplementation\sof\sa\sproposed\s"timediff(X,Y)"\sSQL\sfunction. +D 2023-05-29T18:01:42.123 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -583,7 +583,7 @@ F src/build.c 5512d5a335334b48d116f1ecd051edef96a60add18ae48e0ea302a395f00f3d9 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c aca9e0c08b400b21238b609aea7c09585396cd770985cf8f475560f69222dad3 +F src/date.c 6ac049e14f0da389ed5f5166d7beefd7c456a736f859f2d82c6a0755d1eb644e F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 05e27e3a55dcfeadf2f7ca95a5c5e0928f182c04640ec1954ffa42f3d5c19341 @@ -2071,8 +2071,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b5b5eaeed3ef55415e27aa04561ab446f3be881b56b7cbf9b8ba3307f0b2bf69 -R a97b6bbc5714e405091cdcf5e322eddf +P 736a79c1491065f4ee77ce644af0e529e555ca733c78dbd55487d55d4ddbe5bd +R 7cd65956485b173b36f53ea0da1803ea +T *branch * timediff +T *sym-timediff * +T -sym-trunk * U drh -Z 1c9966bc9ba55db651e2a9b574f4ed8b +Z 45e81044200c651866d6b14e1f654b51 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6ce0a15694..0f63d3a2bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -736a79c1491065f4ee77ce644af0e529e555ca733c78dbd55487d55d4ddbe5bd \ No newline at end of file +054a195125a273bab026ada5f07cc7c32818007027a1fd028ca59d2f179276d4 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 9b7957bbf0..028c3389e7 100644 --- a/src/date.c +++ b/src/date.c @@ -641,6 +641,25 @@ static const struct { { 4, "year", 14713.0, 31536000.0 }, }; +/* +** If the DateTime p is raw number, try to figure out if it is +** a julian day number of a unix timestamp. Set the p value +** appropriately. +*/ +static void autoAdjustDate(DateTime *p){ + if( !p->rawS || p->validJD ){ + p->rawS = 0; + }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ + && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ + ){ + double r = p->s*1000.0 + 210866760000000.0; + clearYMD_HMS_TZ(p); + p->iJD = (sqlite3_int64)(r + 0.5); + p->validJD = 1; + p->rawS = 0; + } +} + /* ** Process a modifier to a date-time stamp. The modifiers are ** as follows: @@ -684,19 +703,8 @@ static int parseModifier( */ if( sqlite3_stricmp(z, "auto")==0 ){ if( idx>1 ) return 1; /* IMP: R-33611-57934 */ - if( !p->rawS || p->validJD ){ - rc = 0; - p->rawS = 0; - }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ - && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ - ){ - r = p->s*1000.0 + 210866760000000.0; - clearYMD_HMS_TZ(p); - p->iJD = (sqlite3_int64)(r + 0.5); - p->validJD = 1; - p->rawS = 0; - rc = 0; - } + autoAdjustDate(p); + rc = 0; } break; } @@ -1325,6 +1333,61 @@ static void cdateFunc( dateFunc(context, 0, 0); } +/* +** timediff(DATE1, DATE2) +** +** Return the that amount of time that DATE1 is later than DATE2 in +** this format: +** +** +YYYY-MM-DD HH:MM:SS.SSS +** +** The initial "+" becomes "-" if DATE1 occurs before DATE2. +*/ +static void timediffFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime d1, d2; + sqlite3_str *pOut = 0; + char sign = '+'; + int rc; + if( isDate(context, 1, argv, &d1) ) return; + if( isDate(context, 1, &argv[1], &d2) ) return; + autoAdjustDate(&d1); + computeJD(&d1); + autoAdjustDate(&d2); + computeJD(&d2); + pOut = sqlite3_str_new(sqlite3_context_db_handle(context)); + if( pOut==0 ){ + sqlite3_result_error_nomem(context); + return; + } + if( d1.iJD Date: Mon, 29 May 2023 20:33:33 +0000 Subject: [PATCH 2/7] New date/time modifier: (+|-)YYYY-MM-DD HH:MM(:SS.SSS)? FossilOrigin-Name: 3832b8a9ef84d9b53b48dfce9c1e724897cd7b3e05711e01675419655f894eac --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/date.c | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 7bca2b96d2..a1547dded7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prototype\simplementation\sof\sa\sproposed\s"timediff(X,Y)"\sSQL\sfunction. -D 2023-05-29T18:01:42.123 +C New\sdate/time\smodifier:\s\s(+|-)YYYY-MM-DD\sHH:MM(:SS.SSS)? +D 2023-05-29T20:33:33.570 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -583,7 +583,7 @@ F src/build.c 5512d5a335334b48d116f1ecd051edef96a60add18ae48e0ea302a395f00f3d9 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c 6ac049e14f0da389ed5f5166d7beefd7c456a736f859f2d82c6a0755d1eb644e +F src/date.c 3752bcd1a5b90147f28fff2a32877935afe10d79ac33a08f24ddf820c5d2e924 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 05e27e3a55dcfeadf2f7ca95a5c5e0928f182c04640ec1954ffa42f3d5c19341 @@ -2071,11 +2071,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 736a79c1491065f4ee77ce644af0e529e555ca733c78dbd55487d55d4ddbe5bd -R 7cd65956485b173b36f53ea0da1803ea -T *branch * timediff -T *sym-timediff * -T -sym-trunk * +P 054a195125a273bab026ada5f07cc7c32818007027a1fd028ca59d2f179276d4 +R b507ad1612c7c470e9ed65929342a32e U drh -Z 45e81044200c651866d6b14e1f654b51 +Z c8a8d9945ac3ddc516393bf70fb76d82 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0f63d3a2bb..74271f635a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -054a195125a273bab026ada5f07cc7c32818007027a1fd028ca59d2f179276d4 \ No newline at end of file +3832b8a9ef84d9b53b48dfce9c1e724897cd7b3e05711e01675419655f894eac \ No newline at end of file diff --git a/src/date.c b/src/date.c index 028c3389e7..4106bd899c 100644 --- a/src/date.c +++ b/src/date.c @@ -870,11 +870,46 @@ static int parseModifier( case '9': { double rRounder; int i; - for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} + int Y,M,D,H,x; + for(n=1; z[n]; n++){ + if( z[n]==':' ) break; + if( sqlite3Isspace(z[n]) ) break; + if( z[n]=='-' && n==5 && getDigits(&z[1], "40f", &Y)==1 ) break; + } if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ rc = 1; break; } + if( z[n]=='-' ){ + /* A modifier of the form (+|-)YYYY-MM-DD adds or subtracts the + ** specified number of years, months, and days. MM is limited to + ** the range 0-11 and DD is limited to 0-30. + */ + if( z[0]!='+' && z[0]!='-' ) break; /* Must start with +/- */ + if( n!=5 ) break; /* Must be 4-digit YYYY */ + if( getDigits(&z[1], "40f-20a-20d 20c", &Y, &M, &D, &H)!=4 ) break; + if( M>=12 ) break; /* M range 0..11 */ + if( D>=31 ) break; /* D range 0..30 */ + computeYMD_HMS(p); + p->validJD = 0; + if( z[0]=='-' ){ + p->Y -= Y; + p->M -= M; + D = -D; + }else{ + p->Y += Y; + p->M += M; + } + x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; + p->Y += x; + p->M -= x*12; + computeJD(p); + p->validHMS = 0; + p->validYMD = 0; + p->iJD += (i64)D*86400000; + z = &z[12]; + n = 2; + } if( z[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the ** specified number of hours, minutes, seconds, and fractional seconds @@ -916,7 +951,6 @@ static int parseModifier( ){ switch( i ){ case 4: { /* Special processing to add months */ - int x; assert( strcmp(aXformType[i].zName,"month")==0 ); computeYMD_HMS(p); p->M += (int)r; From 6abbef89e681b58852a89a671f03daab83bd0de0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 30 May 2023 02:16:33 +0000 Subject: [PATCH 3/7] Improvements to the timediff() function. Test cases added. Not all test cases are passing. FossilOrigin-Name: 2cf6518140d61e2123dc20f39d7e97e7bce17e7641405df7fd63e1cdda444ae0 --- manifest | 13 +++--- manifest.uuid | 2 +- src/date.c | 100 +++++++++++++++++++++++++++++++++------ test/timediff1.test | 111 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+), 22 deletions(-) create mode 100644 test/timediff1.test diff --git a/manifest b/manifest index a1547dded7..d7e2b18402 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sdate/time\smodifier:\s\s(+|-)YYYY-MM-DD\sHH:MM(:SS.SSS)? -D 2023-05-29T20:33:33.570 +C Improvements\sto\sthe\stimediff()\sfunction.\s\sTest\scases\sadded.\sNot\sall\stest\ncases\sare\spassing. +D 2023-05-30T02:16:33.896 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -583,7 +583,7 @@ F src/build.c 5512d5a335334b48d116f1ecd051edef96a60add18ae48e0ea302a395f00f3d9 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c 3752bcd1a5b90147f28fff2a32877935afe10d79ac33a08f24ddf820c5d2e924 +F src/date.c 71c0484764e7d2c4a5f7a98c4e6d3403998eae554a81b3c02a90a1c836049902 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 05e27e3a55dcfeadf2f7ca95a5c5e0928f182c04640ec1954ffa42f3d5c19341 @@ -1605,6 +1605,7 @@ F test/threadtest3.c 655bff6c0895ec03f014126aa65e808fac9aae8c5a7a7da58a510cbe8b4 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 +F test/timediff1.test 701eea6ce725d71305d64292b44d9a0154b7c99ce09c916f9386de3e71689918 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6 F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96 @@ -2071,8 +2072,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 054a195125a273bab026ada5f07cc7c32818007027a1fd028ca59d2f179276d4 -R b507ad1612c7c470e9ed65929342a32e +P 3832b8a9ef84d9b53b48dfce9c1e724897cd7b3e05711e01675419655f894eac +R 8ffc400398f351d057bce50fed0005bf U drh -Z c8a8d9945ac3ddc516393bf70fb76d82 +Z 6414db32510ab8f356b11e69a29d6be4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 74271f635a..7c9c1ef877 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3832b8a9ef84d9b53b48dfce9c1e724897cd7b3e05711e01675419655f894eac \ No newline at end of file +2cf6518140d61e2123dc20f39d7e97e7bce17e7641405df7fd63e1cdda444ae0 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 4106bd899c..6c1acaa9ae 100644 --- a/src/date.c +++ b/src/date.c @@ -871,6 +871,7 @@ static int parseModifier( double rRounder; int i; int Y,M,D,H,x; + const char *z2 = z; for(n=1; z[n]; n++){ if( z[n]==':' ) break; if( sqlite3Isspace(z[n]) ) break; @@ -907,16 +908,16 @@ static int parseModifier( p->validHMS = 0; p->validYMD = 0; p->iJD += (i64)D*86400000; - z = &z[12]; + z2 = &z[12]; n = 2; } - if( z[n]==':' ){ + if( z2[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the ** specified number of hours, minutes, seconds, and fractional seconds ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be ** omitted. */ - const char *z2 = z; + DateTime tx; sqlite3_int64 day; if( !sqlite3Isdigit(*z2) ) z2++; @@ -1370,12 +1371,15 @@ static void cdateFunc( /* ** timediff(DATE1, DATE2) ** -** Return the that amount of time that DATE1 is later than DATE2 in -** this format: +** Return the amount of time that must be added to DATE2 in order to +** convert it into DATE2. The time difference format is: ** ** +YYYY-MM-DD HH:MM:SS.SSS ** -** The initial "+" becomes "-" if DATE1 occurs before DATE2. +** The initial "+" becomes "-" if DATE1 occurs before DATE2. For +** date/time values A and B, the following invariant should hold: +** +** datetime(A) == (datetime(B, timediff(A,B)) */ static void timediffFunc( sqlite3_context *context, @@ -1384,8 +1388,9 @@ static void timediffFunc( ){ DateTime d1, d2; sqlite3_str *pOut = 0; - char sign = '+'; + char sign; int rc; + int Y, M; if( isDate(context, 1, argv, &d1) ) return; if( isDate(context, 1, &argv[1], &d2) ) return; autoAdjustDate(&d1); @@ -1397,20 +1402,85 @@ static void timediffFunc( sqlite3_result_error_nomem(context); return; } - if( d1.iJD=d2.iJD ){ + sign = '+'; + Y = d1.Y - d2.Y; + if( Y ){ + d2.Y = d1.Y; + d2.validJD = 0; + computeJD(&d2); + } + M = d1.M - d2.M; + if( M<0 ){ + Y--; + d2.Y--; + M += 12; + } + if( M!=0 ){ + d2.M = d1.M; + d2.validJD = 0; + computeJD(&d2); + } + if( d1.iJDd2.iJD ){ + M--; + if( M<0 ){ + M = 11; + Y--; + } + d2.M++; + if( d2.M>12 ){ + d2.M = 1; + d2.Y++; + } + d2.validJD = 0; + computeJD(&d2); + } + d1.iJD = d2.iJD - d1.iJD; + d1.iJD += 148699540800000; } d1.validYMD = 0; d1.validHMS = 0; d1.validTZ = 0; - d1.iJD -= d2.iJD; - d1.iJD += 148699540800000; computeYMD_HMS(&d1); - sqlite3_str_appendf(pOut, "%c%04d-%02d-%02d %02d:%02d:%07.3f", - sign, d1.Y, d1.M-1, d1.D-1, d1.h, d1.m, d1.s); + sqlite3_str_appendf(pOut, "%c%04d-%02d-%02d %02d:%02d:%06.3f", + sign, Y, M, d1.D-1, d1.h, d1.m, d1.s); rc = sqlite3_str_errcode(pOut); if( rc ){ sqlite3_free(sqlite3_str_finish(pOut)); diff --git a/test/timediff1.test b/test/timediff1.test new file mode 100644 index 0000000000..b9a38b9c52 --- /dev/null +++ b/test/timediff1.test @@ -0,0 +1,111 @@ +# 2023-05-30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing date and time functions. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Skip this whole file if date and time functions are omitted +# at compile-time +# +ifcapable {!datetime} { + finish_test + return +} + +proc datetest {tnum expr result} { + do_test timediff-$tnum [subst { + execsql "SELECT coalesce($expr,'NULL')" + }] [list $result] +} +set tcl_precision 15 + + +# February overflow on a leap year +datetest 1.1 {datetime('2000-01-31','+1 month')} {2000-03-02 00:00:00} +datetest 1.2 {datetime('2004-01-29','+1 month')} {2004-02-29 00:00:00} +datetest 1.3 {datetime('2000-03-01','-1 day')} {2000-02-29 00:00:00} +datetest 1.4 {datetime('2000-03-31','-1 month')} {2000-03-02 00:00:00} +datetest 1.5 {datetime('2000-03-30','-1 month')} {2000-03-01 00:00:00} +datetest 1.6 {datetime('2000-03-29','-1 month')} {2000-02-29 00:00:00} +datetest 1.7 {datetime('2000-03-28','-1 month')} {2000-02-28 00:00:00} +datetest 1.8 {datetime('2000-02-29','+1 year')} {2001-03-01 00:00:00} +datetest 1.9 {datetime('2000-02-29','+4 years')} {2004-02-29 00:00:00} + +datetest 1.10 {datetime('1998-11-10','+0001-03-19 12:34:56')} \ + {2000-02-29 12:34:56} +datetest 1.11 {datetime('2000-01-31','+0004-01-00 12:34:56')} \ + {2004-03-02 12:34:56} +datetest 1.12 {datetime('2000-01-29','+0008-01-00 12:34:56')} \ + {2008-02-29 12:34:56} +datetest 1.13 {datetime('2001-03-31','-0001-01-00 06:10')} \ + {2000-03-01 17:50:00} + + +# February overflow on a non-leap year +datetest 2.1 {datetime('2001-01-31','+1 month')} {2001-03-03 00:00:00} +datetest 2.2 {datetime('2005-01-29','+1 month')} {2005-03-01 00:00:00} +datetest 2.3 {datetime('2001-03-01','-1 day')} {2001-02-28 00:00:00} +datetest 2.4 {datetime('2001-03-31','-1 month')} {2001-03-03 00:00:00} +datetest 2.5 {datetime('2001-03-30','-1 month')} {2001-03-02 00:00:00} +datetest 2.6 {datetime('2001-03-29','-1 month')} {2001-03-01 00:00:00} +datetest 2.7 {datetime('2001-03-28','-1 month')} {2001-02-28 00:00:00} + +datetest 2.10 {datetime('1999-11-10','+0001-03-19 12:34:56')} \ + {2001-03-01 12:34:56} +datetest 2.11 {datetime('2000-01-31','+0005-01-00 12:34:56')} \ + {2005-03-03 12:34:56} +datetest 2.12 {datetime('2000-01-29','+0009-01-00 12:34:56')} \ + {2009-03-01 12:34:56} +datetest 2.13 {datetime('2002-03-31','-0001-01-00 06:10')} \ + {2001-03-02 17:50:00} + +# timediff +datetest 3.1 {timediff('2000-03-02','2000-01-31')} {+0000-01-00 00:00:00.000} +datetest 3.2 {timediff('2000-01-31','2000-03-02')} {-0000-01-02 00:00:00.000} +datetest 3.3 {timediff('2000-03-02','1999-01-31')} {+0001-01-00 00:00:00.000} +datetest 3.4 {timediff('1999-01-31','2000-03-02')} {-0001-01-02 00:00:00.000} + +unset -nocomplain p1 +unset -nocomplain p2 +set p1 { + 1 {0000-01-01 12:34:56} + 2 {1776-07-04 13:00:00} + 3 {-275529600} + 4 {2440587.5} + 5 {2000-05-29 14:26} + 6 {2023-05-29 18:11} + 7 {2050-05-29 14:26} +} +set p2 { + A {1900-02-28 11:00} + B {1900-03-01 12:00} + C {2000-02-29 13:00} + D {2005-04-30 23:59:59} + E {2005-05-01} +} + +foreach {x1 d1} $p1 { + foreach {x2 d2} $p2 { + set r1 [db one {SELECT datetime($d1,'auto')}] + do_execsql_test timediff-4-$x1$x2 { + SELECT datetime($d2, timediff($d1,$d2)); + } [list $r1] + set r2 [db one {SELECT datetime($d2,'auto')}] + do_execsql_test timediff-4-$x2$x1 { + SELECT datetime($d1, timediff($d2,$d1)); + } [list $r2] + } +} + +finish_test From 36a5f1e90cd3e5b1d1823263c3e2b074c42a502b Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 30 May 2023 02:50:32 +0000 Subject: [PATCH 4/7] Problems fixed. All tests are passing now. FossilOrigin-Name: cff293b0a79107def7bfe54fd60ac4a721c5098c85229d9b46a4e2c4cbf34a6a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/date.c | 10 ++++------ test/timediff1.test | 8 +++++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index d7e2b18402..456fbb06b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\stimediff()\sfunction.\s\sTest\scases\sadded.\sNot\sall\stest\ncases\sare\spassing. -D 2023-05-30T02:16:33.896 +C Problems\sfixed.\s\sAll\stests\sare\spassing\snow. +D 2023-05-30T02:50:32.127 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -583,7 +583,7 @@ F src/build.c 5512d5a335334b48d116f1ecd051edef96a60add18ae48e0ea302a395f00f3d9 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c 71c0484764e7d2c4a5f7a98c4e6d3403998eae554a81b3c02a90a1c836049902 +F src/date.c bd35fd6aadd63dd0019ccd54314e74e058d024704fd02ac22e0041b6012fa610 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 05e27e3a55dcfeadf2f7ca95a5c5e0928f182c04640ec1954ffa42f3d5c19341 @@ -1605,7 +1605,7 @@ F test/threadtest3.c 655bff6c0895ec03f014126aa65e808fac9aae8c5a7a7da58a510cbe8b4 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 -F test/timediff1.test 701eea6ce725d71305d64292b44d9a0154b7c99ce09c916f9386de3e71689918 +F test/timediff1.test ff10ea5829bbe7d11c3c9bed75f8cba1cf42b3c23bd68c4f9d6ef8868546eb85 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6 F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96 @@ -2072,8 +2072,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3832b8a9ef84d9b53b48dfce9c1e724897cd7b3e05711e01675419655f894eac -R 8ffc400398f351d057bce50fed0005bf +P 2cf6518140d61e2123dc20f39d7e97e7bce17e7641405df7fd63e1cdda444ae0 +R b57102997b3962a96160f5f593dc69e1 U drh -Z 6414db32510ab8f356b11e69a29d6be4 +Z 1fcaecaf5799b220b4fbf66eb096e19d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7c9c1ef877..0d5bba483b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2cf6518140d61e2123dc20f39d7e97e7bce17e7641405df7fd63e1cdda444ae0 \ No newline at end of file +cff293b0a79107def7bfe54fd60ac4a721c5098c85229d9b46a4e2c4cbf34a6a \ No newline at end of file diff --git a/src/date.c b/src/date.c index 6c1acaa9ae..360f9a57b6 100644 --- a/src/date.c +++ b/src/date.c @@ -1380,6 +1380,10 @@ static void cdateFunc( ** date/time values A and B, the following invariant should hold: ** ** datetime(A) == (datetime(B, timediff(A,B)) +** +** Both DATE arguments must be either a julian day number, or an +** ISO-8601 string. The unix timestamps are not supported by this +** routine. */ static void timediffFunc( sqlite3_context *context, @@ -1393,10 +1397,6 @@ static void timediffFunc( int Y, M; if( isDate(context, 1, argv, &d1) ) return; if( isDate(context, 1, &argv[1], &d2) ) return; - autoAdjustDate(&d1); - computeJD(&d1); - autoAdjustDate(&d2); - computeJD(&d2); pOut = sqlite3_str_new(sqlite3_context_db_handle(context)); if( pOut==0 ){ sqlite3_result_error_nomem(context); @@ -1415,7 +1415,6 @@ static void timediffFunc( M = d1.M - d2.M; if( M<0 ){ Y--; - d2.Y--; M += 12; } if( M!=0 ){ @@ -1450,7 +1449,6 @@ static void timediffFunc( M = d2.M - d1.M; if( M<0 ){ Y--; - d2.Y--; M += 12; } if( M!=0 ){ diff --git a/test/timediff1.test b/test/timediff1.test index b9a38b9c52..07d50713f6 100644 --- a/test/timediff1.test +++ b/test/timediff1.test @@ -81,7 +81,7 @@ unset -nocomplain p2 set p1 { 1 {0000-01-01 12:34:56} 2 {1776-07-04 13:00:00} - 3 {-275529600} + 3 {1969-07-20 20:17} 4 {2440587.5} 5 {2000-05-29 14:26} 6 {2023-05-29 18:11} @@ -93,17 +93,19 @@ set p2 { C {2000-02-29 13:00} D {2005-04-30 23:59:59} E {2005-05-01} + F {1066-10-14} + G {1904-02-29 11:25} } foreach {x1 d1} $p1 { foreach {x2 d2} $p2 { set r1 [db one {SELECT datetime($d1,'auto')}] do_execsql_test timediff-4-$x1$x2 { - SELECT datetime($d2, timediff($d1,$d2)); + SELECT datetime($d2, 'auto', timediff($d1,$d2)); } [list $r1] set r2 [db one {SELECT datetime($d2,'auto')}] do_execsql_test timediff-4-$x2$x1 { - SELECT datetime($d1, timediff($d2,$d1)); + SELECT datetime($d1, 'auto', timediff($d2,$d1)); } [list $r2] } } From 30bb082d3a1c4e9e701a235ccac1b1929900cd38 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 30 May 2023 11:13:56 +0000 Subject: [PATCH 5/7] All date/time modifiers of the form (+/-)YYYY-MM-DD without the following HH:MM:SS.SSS. FossilOrigin-Name: fa9237a8ab803ca3f67fe753516b7bdb98be3d625e8e241ddf9b02509210e225 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/date.c | 18 ++++++++++++++---- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 456fbb06b0..4b7bf71acf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Problems\sfixed.\s\sAll\stests\sare\spassing\snow. -D 2023-05-30T02:50:32.127 +C All\sdate/time\smodifiers\sof\sthe\sform\s(+/-)YYYY-MM-DD\swithout\sthe\sfollowing\nHH:MM:SS.SSS. +D 2023-05-30T11:13:56.499 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -583,7 +583,7 @@ F src/build.c 5512d5a335334b48d116f1ecd051edef96a60add18ae48e0ea302a395f00f3d9 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c bd35fd6aadd63dd0019ccd54314e74e058d024704fd02ac22e0041b6012fa610 +F src/date.c fc60c1a37df9773d0b764a21947ecbf8a28f09b06069f8a4e44ed6c83706c068 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 05e27e3a55dcfeadf2f7ca95a5c5e0928f182c04640ec1954ffa42f3d5c19341 @@ -2072,8 +2072,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2cf6518140d61e2123dc20f39d7e97e7bce17e7641405df7fd63e1cdda444ae0 -R b57102997b3962a96160f5f593dc69e1 +P cff293b0a79107def7bfe54fd60ac4a721c5098c85229d9b46a4e2c4cbf34a6a +R 0943b555654140e47681c2f446f6eb02 U drh -Z 1fcaecaf5799b220b4fbf66eb096e19d +Z 8e551011a7166e1e39c03f9c16d64816 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0d5bba483b..b0c280008f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cff293b0a79107def7bfe54fd60ac4a721c5098c85229d9b46a4e2c4cbf34a6a \ No newline at end of file +fa9237a8ab803ca3f67fe753516b7bdb98be3d625e8e241ddf9b02509210e225 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 360f9a57b6..e675645903 100644 --- a/src/date.c +++ b/src/date.c @@ -870,7 +870,7 @@ static int parseModifier( case '9': { double rRounder; int i; - int Y,M,D,H,x; + int Y,M,D,h,m,x; const char *z2 = z; for(n=1; z[n]; n++){ if( z[n]==':' ) break; @@ -888,7 +888,7 @@ static int parseModifier( */ if( z[0]!='+' && z[0]!='-' ) break; /* Must start with +/- */ if( n!=5 ) break; /* Must be 4-digit YYYY */ - if( getDigits(&z[1], "40f-20a-20d 20c", &Y, &M, &D, &H)!=4 ) break; + if( getDigits(&z[1], "40f-20a-20d", &Y, &M, &D)!=3 ) break; if( M>=12 ) break; /* M range 0..11 */ if( D>=31 ) break; /* D range 0..30 */ computeYMD_HMS(p); @@ -908,8 +908,18 @@ static int parseModifier( p->validHMS = 0; p->validYMD = 0; p->iJD += (i64)D*86400000; - z2 = &z[12]; - n = 2; + if( z[11]==0 ){ + rc = 0; + break; + } + if( sqlite3Isspace(z[11]) + && getDigits(&z[12], "20c:20e", &h, &m)==2 + ){ + z2 = &z[12]; + n = 2; + }else{ + break; + } } if( z2[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the From cc4bfd96237aaa22c9688196ca9253c78d56e17e Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 30 May 2023 11:51:45 +0000 Subject: [PATCH 6/7] New test cases for the timediff enhancements. FossilOrigin-Name: f14633ce6ddf28a14b03e2da623d96e439966aa3fc30c26cb0be59c0e15b3e9c --- manifest | 12 +++++----- manifest.uuid | 2 +- test/timediff1.test | 58 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 4b7bf71acf..79f5fd15df 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C All\sdate/time\smodifiers\sof\sthe\sform\s(+/-)YYYY-MM-DD\swithout\sthe\sfollowing\nHH:MM:SS.SSS. -D 2023-05-30T11:13:56.499 +C New\stest\scases\sfor\sthe\stimediff\senhancements. +D 2023-05-30T11:51:45.702 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1605,7 +1605,7 @@ F test/threadtest3.c 655bff6c0895ec03f014126aa65e808fac9aae8c5a7a7da58a510cbe8b4 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 -F test/timediff1.test ff10ea5829bbe7d11c3c9bed75f8cba1cf42b3c23bd68c4f9d6ef8868546eb85 +F test/timediff1.test 635b0e1857d1a3519382ae1a0aff9580c33e550c5a5cbec600b5edd2e0487018 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6 F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96 @@ -2072,8 +2072,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cff293b0a79107def7bfe54fd60ac4a721c5098c85229d9b46a4e2c4cbf34a6a -R 0943b555654140e47681c2f446f6eb02 +P fa9237a8ab803ca3f67fe753516b7bdb98be3d625e8e241ddf9b02509210e225 +R 51c5fa7aa16d0c81c327481e1cc4975e U drh -Z 8e551011a7166e1e39c03f9c16d64816 +Z dfeb1c0c465184df485198331681092e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b0c280008f..370e1dd09f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa9237a8ab803ca3f67fe753516b7bdb98be3d625e8e241ddf9b02509210e225 \ No newline at end of file +f14633ce6ddf28a14b03e2da623d96e439966aa3fc30c26cb0be59c0e15b3e9c \ No newline at end of file diff --git a/test/timediff1.test b/test/timediff1.test index 07d50713f6..79000af1d4 100644 --- a/test/timediff1.test +++ b/test/timediff1.test @@ -88,26 +88,62 @@ set p1 { 7 {2050-05-29 14:26} } set p2 { - A {1900-02-28 11:00} - B {1900-03-01 12:00} - C {2000-02-29 13:00} - D {2005-04-30 23:59:59} - E {2005-05-01} - F {1066-10-14} - G {1904-02-29 11:25} + A {1066-10-14} + B {1900-02-28 11:00} + C {1900-03-01 12:00} + D {1904-02-29 11:25} + E {2000-02-29 13:00} + E {2000-03-01 14:00} + F {2001-03-31 15:15} + G {2002-04-01 16:59} + H {2003-04-30 17:00} + I {2004-05-01 23:59:59} + J {2005-06-01} + K {2006-06-30 01:23:45} + L {2007-12-31 02:00} + M {2008-01-01 01:59} } foreach {x1 d1} $p1 { foreach {x2 d2} $p2 { - set r1 [db one {SELECT datetime($d1,'auto')}] + set r1 [db one {SELECT datetime($d1)}] do_execsql_test timediff-4-$x1$x2 { - SELECT datetime($d2, 'auto', timediff($d1,$d2)); + SELECT datetime($d2, timediff($d1,$d2)); } [list $r1] - set r2 [db one {SELECT datetime($d2,'auto')}] + set r2 [db one {SELECT datetime($d2)}] do_execsql_test timediff-4-$x2$x1 { - SELECT datetime($d1, 'auto', timediff($d2,$d1)); + SELECT datetime($d1, timediff($d2,$d1)); } [list $r2] } } +# Partial time-diffs as modifiers +# +datetest 5-1 {datetime('2000-01-01','+0001-02-03')} {2001-03-04 00:00:00} +datetest 5-2 {datetime('2000-01-01','+0001-02-03x')} {NULL} +datetest 5-3 {datetime('2000-01-01','+0001-11-03')} {2001-12-04 00:00:00} +datetest 5-4 {datetime('2000-01-01','+0001-12-03')} {NULL} +datetest 5-5 {datetime('2000-01-01','+0001-02-30')} {2001-03-31 00:00:00} +datetest 5-6 {datetime('2000-01-01','+0001-02-31')} {NULL} +datetest 5-7 {datetime('2000-01-01','+0001-02-03 0')} {NULL} +datetest 5-8 {datetime('2000-01-01','+0001-02-03 01')} {NULL} +datetest 5-9 {datetime('2000-01-01','+0001-02-03 01:')} {NULL} +datetest 5-10 {datetime('2000-01-01','+0001-02-03 01:0')} {NULL} +datetest 5-11 {datetime('2000-01-01','+0001-02-03 01:02')} {2001-03-04 01:02:00} +datetest 5-12 {datetime('2000-01-01','+0001-02-03 01:02:')} {NULL} +datetest 5-13 {datetime('2000-01-01','+0001-02-03 01:02:0')} {NULL} +datetest 5-14 {datetime('2000-01-01','+0001-02-03 01:02:03')} \ + {2001-03-04 01:02:03} +datetest 5-15 {datetime('2000-01-01','+0001-02-03 01:02:03.')} NULL +datetest 5-16 {datetime('2000-01-01','+0001-02-03 01:02:03.5')} \ + {2001-03-04 01:02:03} +datetest 5-17 {datetime('2000-01-01','+0001-02-03 01:02:03.50')} \ + {2001-03-04 01:02:03} +datetest 5-18 {datetime('2000-01-01','+0001-02-03 01:02:03.500')} \ + {2001-03-04 01:02:03} +datetest 5-19 {datetime('2000-01-01','+0001-02-03 01:02:03.500x')} {NULL} +datetest 5-20 {datetime('2000-01-01','+0001-02-03 01:02:03.500 x')} {NULL} + + + finish_test From 7d65f1bec0e380d2f6d2beb85569b16c4677fed4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 30 May 2023 14:46:30 +0000 Subject: [PATCH 7/7] Simplifications to the new timediff() logic. FossilOrigin-Name: d6954259bd3f8475f3804fd02a1591d037efa9df54da45776863c024ff90e596 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/date.c | 26 +++++++------------------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 79f5fd15df..e8c3252756 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases\sfor\sthe\stimediff\senhancements. -D 2023-05-30T11:51:45.702 +C Simplifications\sto\sthe\snew\stimediff()\slogic. +D 2023-05-30T14:46:30.043 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -583,7 +583,7 @@ F src/build.c 5512d5a335334b48d116f1ecd051edef96a60add18ae48e0ea302a395f00f3d9 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c fc60c1a37df9773d0b764a21947ecbf8a28f09b06069f8a4e44ed6c83706c068 +F src/date.c cb71f73d5df5303ec6630971b9c8b8c7df466fa3233dbdc643d613806e53e554 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 05e27e3a55dcfeadf2f7ca95a5c5e0928f182c04640ec1954ffa42f3d5c19341 @@ -2072,8 +2072,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fa9237a8ab803ca3f67fe753516b7bdb98be3d625e8e241ddf9b02509210e225 -R 51c5fa7aa16d0c81c327481e1cc4975e +P f14633ce6ddf28a14b03e2da623d96e439966aa3fc30c26cb0be59c0e15b3e9c +R 200e909133393bbb7ad7eb71a74582fc U drh -Z dfeb1c0c465184df485198331681092e +Z a8e1aeb111a402709c4efa768d7bf30a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 370e1dd09f..888730ba20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f14633ce6ddf28a14b03e2da623d96e439966aa3fc30c26cb0be59c0e15b3e9c \ No newline at end of file +d6954259bd3f8475f3804fd02a1591d037efa9df54da45776863c024ff90e596 \ No newline at end of file diff --git a/src/date.c b/src/date.c index e675645903..dfb727155b 100644 --- a/src/date.c +++ b/src/date.c @@ -887,7 +887,7 @@ static int parseModifier( ** the range 0-11 and DD is limited to 0-30. */ if( z[0]!='+' && z[0]!='-' ) break; /* Must start with +/- */ - if( n!=5 ) break; /* Must be 4-digit YYYY */ + if( NEVER(n!=5) ) break; /* Must be 4-digit YYYY */ if( getDigits(&z[1], "40f-20a-20d", &Y, &M, &D)!=3 ) break; if( M>=12 ) break; /* M range 0..11 */ if( D>=31 ) break; /* D range 0..30 */ @@ -1400,18 +1400,12 @@ static void timediffFunc( int argc, sqlite3_value **argv ){ - DateTime d1, d2; - sqlite3_str *pOut = 0; char sign; - int rc; int Y, M; + DateTime d1, d2; + sqlite3_str sRes; if( isDate(context, 1, argv, &d1) ) return; if( isDate(context, 1, &argv[1], &d2) ) return; - pOut = sqlite3_str_new(sqlite3_context_db_handle(context)); - if( pOut==0 ){ - sqlite3_result_error_nomem(context); - return; - } computeYMD_HMS(&d1); computeYMD_HMS(&d2); if( d1.iJD>=d2.iJD ){ @@ -1439,7 +1433,7 @@ static void timediffFunc( Y--; } d2.M--; - if( d2.M<0 ){ + if( d2.M<1 ){ d2.M = 12; d2.Y--; } @@ -1487,16 +1481,10 @@ static void timediffFunc( d1.validHMS = 0; d1.validTZ = 0; computeYMD_HMS(&d1); - sqlite3_str_appendf(pOut, "%c%04d-%02d-%02d %02d:%02d:%06.3f", + sqlite3StrAccumInit(&sRes, 0, 0, 0, 100); + sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f", sign, Y, M, d1.D-1, d1.h, d1.m, d1.s); - rc = sqlite3_str_errcode(pOut); - if( rc ){ - sqlite3_free(sqlite3_str_finish(pOut)); - sqlite3_result_error_code(context, rc); - }else{ - sqlite3_result_text(context, - sqlite3_str_finish(pOut), -1, sqlite3_free); - } + sqlite3ResultStrAccum(context, &sRes); }