Enhancements to date/time functions:
(1) Add support for time-shift modifiers of the form (+|-)YYYY-MM-DD HH:MM:SS.SSS (2) Add the timediff(A,B) SQL function that returns the time-shift modifier sufficient to move B to A. FossilOrigin-Name: 574bf370b0b9a72eb0468e0e121d4d6171fc533883b66d335f6794ef5ee1f051
This commit is contained in:
commit
8eb9c06e65
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
|||||||
C Minor\stweak\sto\sthe\sOPFS\sasync\sproxy\sto\sattempt\sto\saccount\sfor\sa\sspurious\shigh-load\sconsole\serror\smessage\swhich\swas\sreported\svia\sthe\ssqlite-wasm\snpm\sproject.
|
C Enhancements\sto\sdate/time\sfunctions:\n(1)\sAdd\ssupport\sfor\stime-shift\smodifiers\sof\sthe\sform\s(+|-)YYYY-MM-DD\sHH:MM:SS.SSS\n(2)\sAdd\sthe\stimediff(A,B)\sSQL\sfunction\sthat\sreturns\sthe\stime-shift\smodifier\nsufficient\sto\smove\sB\sto\sA.
|
||||||
D 2023-05-30T14:10:28.641
|
D 2023-05-30T16:40:42.849
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@ -583,7 +583,7 @@ F src/build.c 5512d5a335334b48d116f1ecd051edef96a60add18ae48e0ea302a395f00f3d9
|
|||||||
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
|
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
|
||||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||||
F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d
|
F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d
|
||||||
F src/date.c aca9e0c08b400b21238b609aea7c09585396cd770985cf8f475560f69222dad3
|
F src/date.c cb71f73d5df5303ec6630971b9c8b8c7df466fa3233dbdc643d613806e53e554
|
||||||
F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387
|
F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387
|
||||||
F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef
|
F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef
|
||||||
F src/delete.c 05e27e3a55dcfeadf2f7ca95a5c5e0928f182c04640ec1954ffa42f3d5c19341
|
F src/delete.c 05e27e3a55dcfeadf2f7ca95a5c5e0928f182c04640ec1954ffa42f3d5c19341
|
||||||
@ -1605,6 +1605,7 @@ F test/threadtest3.c 655bff6c0895ec03f014126aa65e808fac9aae8c5a7a7da58a510cbe8b4
|
|||||||
F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
|
F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
|
||||||
F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421
|
F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421
|
||||||
F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90
|
F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90
|
||||||
|
F test/timediff1.test 635b0e1857d1a3519382ae1a0aff9580c33e550c5a5cbec600b5edd2e0487018
|
||||||
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
|
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
|
||||||
F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6
|
F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6
|
||||||
F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96
|
F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96
|
||||||
@ -2071,8 +2072,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 68abee3c1bf4e9ff632fccaa6ac7c5c4cdf55c4ff1749830ae3bd5ff6d55ebb2
|
P a61467d1fbb7a2804bfdc685a38e0b738747b9afd42c25a78a938b114a822f61 d6954259bd3f8475f3804fd02a1591d037efa9df54da45776863c024ff90e596
|
||||||
R e35de080a5d8c160cf20199fde831e23
|
R 255227b4547145c8dcfb80a734de5898
|
||||||
U stephan
|
T +closed d6954259bd3f8475f3804fd02a1591d037efa9df54da45776863c024ff90e596
|
||||||
Z a6e965e2f0231d43e4b927decea2e440
|
U drh
|
||||||
|
Z b0a2fbca407b458dcbae70cd95c3b03c
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
a61467d1fbb7a2804bfdc685a38e0b738747b9afd42c25a78a938b114a822f61
|
574bf370b0b9a72eb0468e0e121d4d6171fc533883b66d335f6794ef5ee1f051
|
198
src/date.c
198
src/date.c
@ -641,6 +641,25 @@ static const struct {
|
|||||||
{ 4, "year", 14713.0, 31536000.0 },
|
{ 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
|
** Process a modifier to a date-time stamp. The modifiers are
|
||||||
** as follows:
|
** as follows:
|
||||||
@ -684,19 +703,8 @@ static int parseModifier(
|
|||||||
*/
|
*/
|
||||||
if( sqlite3_stricmp(z, "auto")==0 ){
|
if( sqlite3_stricmp(z, "auto")==0 ){
|
||||||
if( idx>1 ) return 1; /* IMP: R-33611-57934 */
|
if( idx>1 ) return 1; /* IMP: R-33611-57934 */
|
||||||
if( !p->rawS || p->validJD ){
|
autoAdjustDate(p);
|
||||||
rc = 0;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -862,18 +870,64 @@ static int parseModifier(
|
|||||||
case '9': {
|
case '9': {
|
||||||
double rRounder;
|
double rRounder;
|
||||||
int i;
|
int i;
|
||||||
for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
|
int Y,M,D,h,m,x;
|
||||||
|
const char *z2 = z;
|
||||||
|
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 ){
|
if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){
|
||||||
rc = 1;
|
rc = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( z[n]==':' ){
|
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( 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 */
|
||||||
|
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;
|
||||||
|
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
|
/* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
|
||||||
** specified number of hours, minutes, seconds, and fractional seconds
|
** specified number of hours, minutes, seconds, and fractional seconds
|
||||||
** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be
|
** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be
|
||||||
** omitted.
|
** omitted.
|
||||||
*/
|
*/
|
||||||
const char *z2 = z;
|
|
||||||
DateTime tx;
|
DateTime tx;
|
||||||
sqlite3_int64 day;
|
sqlite3_int64 day;
|
||||||
if( !sqlite3Isdigit(*z2) ) z2++;
|
if( !sqlite3Isdigit(*z2) ) z2++;
|
||||||
@ -908,7 +962,6 @@ static int parseModifier(
|
|||||||
){
|
){
|
||||||
switch( i ){
|
switch( i ){
|
||||||
case 4: { /* Special processing to add months */
|
case 4: { /* Special processing to add months */
|
||||||
int x;
|
|
||||||
assert( strcmp(aXformType[i].zName,"month")==0 );
|
assert( strcmp(aXformType[i].zName,"month")==0 );
|
||||||
computeYMD_HMS(p);
|
computeYMD_HMS(p);
|
||||||
p->M += (int)r;
|
p->M += (int)r;
|
||||||
@ -1325,6 +1378,116 @@ static void cdateFunc(
|
|||||||
dateFunc(context, 0, 0);
|
dateFunc(context, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** timediff(DATE1, DATE2)
|
||||||
|
**
|
||||||
|
** 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. For
|
||||||
|
** 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,
|
||||||
|
int argc,
|
||||||
|
sqlite3_value **argv
|
||||||
|
){
|
||||||
|
char sign;
|
||||||
|
int Y, M;
|
||||||
|
DateTime d1, d2;
|
||||||
|
sqlite3_str sRes;
|
||||||
|
if( isDate(context, 1, argv, &d1) ) return;
|
||||||
|
if( isDate(context, 1, &argv[1], &d2) ) return;
|
||||||
|
computeYMD_HMS(&d1);
|
||||||
|
computeYMD_HMS(&d2);
|
||||||
|
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--;
|
||||||
|
M += 12;
|
||||||
|
}
|
||||||
|
if( M!=0 ){
|
||||||
|
d2.M = d1.M;
|
||||||
|
d2.validJD = 0;
|
||||||
|
computeJD(&d2);
|
||||||
|
}
|
||||||
|
if( d1.iJD<d2.iJD ){
|
||||||
|
M--;
|
||||||
|
if( M<0 ){
|
||||||
|
M = 11;
|
||||||
|
Y--;
|
||||||
|
}
|
||||||
|
d2.M--;
|
||||||
|
if( d2.M<1 ){
|
||||||
|
d2.M = 12;
|
||||||
|
d2.Y--;
|
||||||
|
}
|
||||||
|
d2.validJD = 0;
|
||||||
|
computeJD(&d2);
|
||||||
|
}
|
||||||
|
d1.iJD -= d2.iJD;
|
||||||
|
d1.iJD += 148699540800000;
|
||||||
|
}else{
|
||||||
|
sign = '-';
|
||||||
|
Y = d2.Y - d1.Y;
|
||||||
|
if( Y ){
|
||||||
|
d2.Y = d1.Y;
|
||||||
|
d2.validJD = 0;
|
||||||
|
computeJD(&d2);
|
||||||
|
}
|
||||||
|
M = d2.M - d1.M;
|
||||||
|
if( M<0 ){
|
||||||
|
Y--;
|
||||||
|
M += 12;
|
||||||
|
}
|
||||||
|
if( M!=0 ){
|
||||||
|
d2.M = d1.M;
|
||||||
|
d2.validJD = 0;
|
||||||
|
computeJD(&d2);
|
||||||
|
}
|
||||||
|
if( d1.iJD>d2.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;
|
||||||
|
computeYMD_HMS(&d1);
|
||||||
|
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);
|
||||||
|
sqlite3ResultStrAccum(context, &sRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** current_timestamp()
|
** current_timestamp()
|
||||||
**
|
**
|
||||||
@ -1399,6 +1562,7 @@ void sqlite3RegisterDateTimeFunctions(void){
|
|||||||
PURE_DATE(time, -1, 0, 0, timeFunc ),
|
PURE_DATE(time, -1, 0, 0, timeFunc ),
|
||||||
PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
|
PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
|
||||||
PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
|
PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
|
||||||
|
PURE_DATE(timediff, 2, 0, 0, timediffFunc ),
|
||||||
DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
|
DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
|
||||||
DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
|
DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
|
||||||
DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
|
DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
|
||||||
|
149
test/timediff1.test
Normal file
149
test/timediff1.test
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
# 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 {1969-07-20 20:17}
|
||||||
|
4 {2440587.5}
|
||||||
|
5 {2000-05-29 14:26}
|
||||||
|
6 {2023-05-29 18:11}
|
||||||
|
7 {2050-05-29 14:26}
|
||||||
|
}
|
||||||
|
set p2 {
|
||||||
|
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)}]
|
||||||
|
do_execsql_test timediff-4-$x1$x2 {
|
||||||
|
SELECT datetime($d2, timediff($d1,$d2));
|
||||||
|
} [list $r1]
|
||||||
|
set r2 [db one {SELECT datetime($d2)}]
|
||||||
|
do_execsql_test timediff-4-$x2$x1 {
|
||||||
|
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
|
Loading…
x
Reference in New Issue
Block a user