1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Prototype implementation of a proposed "timediff(X,Y)" SQL function.

FossilOrigin-Name: 054a195125a273bab026ada5f07cc7c32818007027a1fd028ca59d2f179276d4
This commit is contained in:
drh
2023-05-29 18:01:42 +00:00
parent 4308b88dcd
commit 0cbc2143b9
3 changed files with 87 additions and 20 deletions

View File

@@ -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<d2.iJD ){
sign = '-';
DateTime x = d1;
d1 = d2;
d2 = x;
}
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);
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);
}
}
/*
** current_timestamp()
**
@@ -1399,6 +1462,7 @@ void sqlite3RegisterDateTimeFunctions(void){
PURE_DATE(time, -1, 0, 0, timeFunc ),
PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
PURE_DATE(timediff, 2, 0, 0, timediffFunc ),
DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
DFUNCTION(current_date, 0, 0, 0, cdateFunc ),