1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Add a new modifier to date/time functions: "subsecond". May be

abbreviated as just "subsec".  This modifier causes functions to try
to show fractional seconds if they do not already.

FossilOrigin-Name: 03f2a15e8779d8ca76510badeabde62a0539ce8a6368d7a9688f5aadc215b940
This commit is contained in:
drh
2023-04-21 15:30:47 +00:00
parent 88ed723490
commit 11d5efde75
3 changed files with 84 additions and 26 deletions

View File

@@ -77,6 +77,7 @@ struct DateTime {
char validTZ; /* True (1) if tz is valid */
char tzSet; /* Timezone was set explicitly */
char isError; /* An overflow has occurred */
char useSubsec; /* Display subsecond precision */
};
@@ -391,6 +392,11 @@ static int parseDateOrTime(
}else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){
setRawDateNumber(p, r);
return 0;
}else if( (sqlite3StrICmp(zDate,"subsec")==0
|| sqlite3StrICmp(zDate,"subsecond")==0)
&& sqlite3NotPureFunc(context) ){
p->useSubsec = 1;
return setDateTimeToCurrent(context, p);
}
return 1;
}
@@ -805,8 +811,22 @@ static int parseModifier(
**
** Move the date backwards to the beginning of the current day,
** or month or year.
**
** subsecond
** subsec
**
** Show subsecond precision in the output of datetime() and
** unixepoch() and strftime('%s').
*/
if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break;
if( sqlite3_strnicmp(z, "start of ", 9)!=0 ){
if( sqlite3_stricmp(z, "subsec")==0
|| sqlite3_stricmp(z, "subsecond")==0
){
p->useSubsec = 1;
rc = 0;
}
break;
}
if( !p->validJD && !p->validYMD && !p->validHMS ) break;
z += 9;
computeYMD(p);
@@ -1004,7 +1024,11 @@ static void unixepochFunc(
DateTime x;
if( isDate(context, argc, argv, &x)==0 ){
computeJD(&x);
sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000);
if( x.useSubsec ){
sqlite3_result_double(context, (x.iJD - 21086676*(i64)10000000)/1000.0);
}else{
sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000);
}
}
}
@@ -1020,8 +1044,8 @@ static void datetimeFunc(
){
DateTime x;
if( isDate(context, argc, argv, &x)==0 ){
int Y, s;
char zBuf[24];
int Y, s, n;
char zBuf[32];
computeYMD_HMS(&x);
Y = x.Y;
if( Y<0 ) Y = -Y;
@@ -1042,15 +1066,28 @@ static void datetimeFunc(
zBuf[15] = '0' + (x.m/10)%10;
zBuf[16] = '0' + (x.m)%10;
zBuf[17] = ':';
s = (int)x.s;
zBuf[18] = '0' + (s/10)%10;
zBuf[19] = '0' + (s)%10;
zBuf[20] = 0;
if( x.useSubsec ){
s = (int)1000.0*x.s;
zBuf[18] = '0' + (s/10000)%10;
zBuf[19] = '0' + (s/1000)%10;
zBuf[20] = '.';
zBuf[21] = '0' + (s/100)%10;
zBuf[22] = '0' + (s/10)%10;
zBuf[23] = '0' + (s)%10;
zBuf[24] = 0;
n = 24;
}else{
s = (int)x.s;
zBuf[18] = '0' + (s/10)%10;
zBuf[19] = '0' + (s)%10;
zBuf[20] = 0;
n = 20;
}
if( x.Y<0 ){
zBuf[0] = '-';
sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT);
sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT);
}else{
sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT);
sqlite3_result_text(context, &zBuf[1], n-1, SQLITE_TRANSIENT);
}
}
}
@@ -1067,7 +1104,7 @@ static void timeFunc(
){
DateTime x;
if( isDate(context, argc, argv, &x)==0 ){
int s;
int s, n;
char zBuf[16];
computeHMS(&x);
zBuf[0] = '0' + (x.h/10)%10;
@@ -1076,11 +1113,24 @@ static void timeFunc(
zBuf[3] = '0' + (x.m/10)%10;
zBuf[4] = '0' + (x.m)%10;
zBuf[5] = ':';
s = (int)x.s;
zBuf[6] = '0' + (s/10)%10;
zBuf[7] = '0' + (s)%10;
zBuf[8] = 0;
sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT);
if( x.useSubsec ){
s = (int)1000.0*x.s;
zBuf[6] = '0' + (s/10000)%10;
zBuf[7] = '0' + (s/1000)%10;
zBuf[8] = '.';
zBuf[9] = '0' + (s/100)%10;
zBuf[10] = '0' + (s/10)%10;
zBuf[11] = '0' + (s)%10;
zBuf[12] = 0;
n = 12;
}else{
s = (int)x.s;
zBuf[6] = '0' + (s/10)%10;
zBuf[7] = '0' + (s)%10;
zBuf[8] = 0;
n = 8;
}
sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT);
}
}
@@ -1211,8 +1261,13 @@ static void strftimeFunc(
break;
}
case 's': {
i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000);
sqlite3_str_appendf(&sRes,"%lld",iS);
if( x.useSubsec ){
sqlite3_str_appendf(&sRes,"%.3f",
(x.iJD - 21086676*(i64)10000000)/1000.0);
}else{
i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000);
sqlite3_str_appendf(&sRes,"%lld",iS);
}
break;
}
case 'S': {