-C Fix\sassert()\sstatements\sin\sdate/time\scomputations:\sThe\smonth\sand\sday\snumbers\ncan\sbe\szero\sif\san\serror\shas\sbeen\sseen.
-D 2024-03-04T11:12:15.305
+C Adjust\sdate/time\sfunctions\sso\sthat\sthey\sdo\sa\sbetter\sjob\sof\skeeping\strack\nof\swhether\sthe\scurrent\stime\sis\sUTC\sor\slocaltime,\sand\sno-op\sthe\s'utc'\sand\n'localtime'\smodifiers\saccordingly.\sSee\n[forum:/info/e7a939e074|forum\spost\se7a939e074].\nAlso\sadd\sthe\sdatedebug()\sfunction,\savailable\nonly\sunder\s-DSQLITE_DEBUG,\sfor\simproved\svisibility\sof\sthe\sDateTime\sobject\nduring\sdebugging\sand\stesting.
+D 2024-03-04T13:58:09.237
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 23331529e654be40ca97d171cbbffe9b3d4c71cc53b78fe5501230675952da8b
-F src/date.c 29cecfe69287242a12f753ffc883e4231afde3af501fb1b4a7b721b159fc4bb2
+F src/date.c a9e4382961fb26156a308645f7363519ab7eb20e412e78b7c1fe16bbfbb1689a
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
F test/cursorhint.test 05cf0febe5c5f8a31f199401fd1c9322249e753950d55f26f9d5aca61408a270
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
-F test/date.test 99bfd3a77a3f9ae54eebd374a4301af960f2b2e9a581cf63e26445bae830a435
+F test/date.test c8ff835023f2107b57ce7a45c92265d51c98a23fc93231e998f12d850831aad6
F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1
F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5
F test/date4.test 75dc8401e8c0639a228cd26a6eaa4ff5ea8ccda912b9853d1c9462c476670e17
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
F test/tkt-b75a9ca6b0.test dc6a853c242f7d0326564ae32e9e5eb462b5e8d2bc5b01ea3b18fd24f8e5894b
F test/tkt-ba7cbfaedc.test b4c0deccc12aeb55cfdb57935b16b5d67c5a9877
-F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
+F test/tkt-bd484a090c.test e6af3e3a4242cd8f1c91c736364f09075d8e33e3b86f6492a1ee36278ea71b61
F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
F test/tkt-c48d99d690.test ba61977d62ab612fc515b3c488a6fbd6464a2447
F test/tkt-c694113d5.test 82c461924ada5c14866c47e85535b0b0923ba16a2e907e370061a5ca77f65d77
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P f6e887203365b30cea6e9c145366345e48256a347388577edf2bada65e0655b7
-R 68522a41082e7767e1ccbf426313c9cf
+P fc773f6c76ec114be8b6e25b13885acb5adcc9d052dca0d8d0ff94e2a0743d64
+R 0f693fc7ce53368753332e9082e39c9c
U drh
-Z cb9173c28803c9d207f1634b7853f7aa
+Z b0035812b357d7d3f0f59f737bf36230
# Remove this line to create a well-formed Fossil manifest.
-fc773f6c76ec114be8b6e25b13885acb5adcc9d052dca0d8d0ff94e2a0743d64
\ No newline at end of file
+dc569683748354a6db83438904422e802d3ea780775c48da85b474fff03ca8a1
\ No newline at end of file
char validJD; /* True (1) if iJD is valid */
char validYMD; /* True (1) if Y,M,D are valid */
char validHMS; /* True (1) if h,m,s are valid */
- char validTZ; /* True (1) if tz is valid */
char nFloor; /* Days to implement "floor" */
unsigned rawS : 1; /* Raw numeric value stored in s */
- unsigned tzSet : 1; /* Timezone was set explicitly */
unsigned isError : 1; /* An overflow has occurred */
unsigned useSubsec : 1; /* Display subsecond precision */
+ unsigned isUtc : 1; /* Time is known to be UTC */
+ unsigned isLocal : 1; /* Time is known to be localtime */
};
sgn = +1;
}else if( c=='Z' || c=='z' ){
zDate++;
+ p->isLocal = 0;
+ p->isUtc = 1;
goto zulu_time;
}else{
return c!=0;
p->tz = sgn*(nMn + nHr*60);
zulu_time:
while( sqlite3Isspace(*zDate) ){ zDate++; }
- p->tzSet = 1;
return *zDate!=0;
}
p->m = m;
p->s = s + ms;
if( parseTimezone(zDate, p) ) return 1;
- p->validTZ = (p->tz!=0)?1:0;
return 0;
}
p->validJD = 1;
if( p->validHMS ){
p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5);
- if( p->validTZ ){
+ if( p->tz ){
p->iJD -= p->tz*60000;
p->validYMD = 0;
p->validHMS = 0;
- p->validTZ = 0;
+ p->tz = 0;
+ p->isUtc = 1;
+ p->isLocal = 0;
}
}
}
p->M = M;
p->D = D;
computeFloor(p);
- if( p->validTZ ){
+ if( p->tz ){
computeJD(p);
}
return 0;
-}
+};
+
+
+static void clearYMD_HMS_TZ(DateTime *p); /* Forward declaration */
/*
** Set the time to the current time reported by the VFS.
p->iJD = sqlite3StmtCurrentTime(context);
if( p->iJD>0 ){
p->validJD = 1;
+ p->isUtc = 1;
+ p->isLocal = 0;
+ clearYMD_HMS_TZ(p);
return 0;
}else{
return 1;
static void clearYMD_HMS_TZ(DateTime *p){
p->validYMD = 0;
p->validHMS = 0;
- p->validTZ = 0;
+ p->tz = 0;
}
#ifndef SQLITE_OMIT_LOCALTIME
p->validHMS = 1;
p->validJD = 0;
p->rawS = 0;
- p->validTZ = 0;
+ p->tz = 0;
p->isError = 0;
return SQLITE_OK;
}
** show local time.
*/
if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
- rc = toLocaltime(p, pCtx);
+ rc = p->isLocal ? SQLITE_OK : toLocaltime(p, pCtx);
+ p->isUtc = 0;
+ p->isLocal = 1;
}
break;
}
}
#ifndef SQLITE_OMIT_LOCALTIME
else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
- if( p->tzSet==0 ){
+ if( p->isUtc==0 ){
i64 iOrigJD; /* Original localtime */
i64 iGuess; /* Guess at the corresponding utc time */
int cnt = 0; /* Safety to prevent infinite loop */
memset(p, 0, sizeof(*p));
p->iJD = iGuess;
p->validJD = 1;
- p->tzSet = 1;
+ p->isUtc = 1;
+ p->isLocal = 0;
}
rc = SQLITE_OK;
}
&& r>=0.0 && r<7.0 && (n=(int)r)==r ){
sqlite3_int64 Z;
computeYMD_HMS(p);
- p->validTZ = 0;
+ p->tz = 0;
p->validJD = 0;
computeJD(p);
Z = ((p->iJD + 129600000)/86400000) % 7;
p->h = p->m = 0;
p->s = 0.0;
p->rawS = 0;
- p->validTZ = 0;
+ p->tz = 0;
p->validJD = 0;
if( sqlite3_stricmp(z,"month")==0 ){
p->D = 1;
d1.iJD = d2.iJD - d1.iJD;
d1.iJD += (u64)1486995408 * (u64)100000;
}
- d1.validYMD = 0;
- d1.validHMS = 0;
- d1.validTZ = 0;
+ clearYMD_HMS_TZ(&d1);
computeYMD_HMS(&d1);
sqlite3StrAccumInit(&sRes, 0, 0, 0, 100);
sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f",
}
#endif
+#if !defined(SQLITE_OMIT_DATETIME_FUNCS) && defined(SQLITE_DEBUG)
+/*
+** datedebug(...)
+**
+** This routine returns JSON that describes the internal DateTime object.
+** Used for debugging and testing only. Subject to change.
+*/
+static void datedebugFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ DateTime x;
+ if( isDate(context, argc, argv, &x)==0 ){
+ char *zJson;
+ zJson = sqlite3_mprintf(
+ "{iJD:%lld,Y:%d,M:%d,D:%d,h:%d,m:%d,tz:%d,"
+ "s:%.3f,validJD:%d,validYMS:%d,validHMS:%d,"
+ "nFloor:%d,rawS:%d,isError:%d,useSubsec:%d,"
+ "isUtc:%d,isLocal:%d}",
+ x.iJD, x.Y, x.M, x.D, x.h, x.m, x.tz,
+ x.s, x.validJD, x.validYMD, x.validHMS,
+ x.nFloor, x.rawS, x.isError, x.useSubsec,
+ x.isUtc, x.isLocal);
+ sqlite3_result_text(context, zJson, -1, sqlite3_free);
+ }
+}
+#endif /* !SQLITE_OMIT_DATETIME_FUNCS && SQLITE_DEBUG */
+
+
/*
** This function registered all of the above C functions as SQL
** functions. This should be the only routine in this file with
PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
PURE_DATE(timediff, 2, 0, 0, timediffFunc ),
+#ifdef SQLITE_DEBUG
+ PURE_DATE(datedebug, -1, 0, 0, datedebugFunc ),
+#endif
DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
# localtime->utc and utc->localtime conversions.
#
# Use SQLITE_TESTCTRL_LOCALTIME_FAULT=2 to set an alternative localtime_r()
-# implementation that is not locale-dependent. This testing localtime_r()
+# implementation that is not locale-dependent. The testing localtime_r()
# operates as follows:
#
# (1) Localtime is 30 minutes earlier than (west of) UTC on
local_to_utc 6.23 {3000-10-30 12:00:00} {3000-10-30 11:30:00}
utc_to_local 6.24 {3000-10-30 11:30:00} {3000-10-30 12:00:00}
+# If the time is specified to be ZULU, or if it has an explicit
+# timezone extension, then the time will already be UTC and subsequent
+# 'utc' modifiers are no-ops.
+#
+do_execsql_test date-6.25 {
+ SELECT datetime('2000-10-29 12:00Z','utc','utc');
+} {{2000-10-29 12:00:00}}
+do_execsql_test date-6.26 {
+ SELECT datetime('2000-10-29 12:00:00+05:00');
+} {{2000-10-29 07:00:00}}
+do_execsql_test date-6.27 {
+ SELECT datetime('2000-10-29 12:00:00+05:00', 'utc');
+} {{2000-10-29 07:00:00}}
+
+# Multiple back-and-forth UTC to LOCAL to UTC...
+do_execsql_test date-6.28 {
+ SELECT datetime('2000-10-29 12:00:00Z', 'localtime');
+} {{2000-10-29 12:30:00}}
+do_execsql_test date-6.29 {
+ SELECT datetime('2000-10-29 12:00:00Z', 'utc', 'localtime');
+} {{2000-10-29 12:30:00}}
+do_execsql_test date-6.30 {
+ SELECT datetime('2000-10-29 12:00:00Z', 'utc', 'localtime', 'utc');
+} {{2000-10-29 12:00:00}}
+do_execsql_test date-6.31 {
+ SELECT datetime('2000-10-29 12:00:00Z', 'utc','localtime','utc','localtime');
+} {{2000-10-29 12:30:00}}
+do_execsql_test date-6.32 {
+ SELECT datetime('2000-10-29 12:00:00Z', 'localtime','localtime');
+} {{2000-10-29 12:30:00}}
+
+
# Restore the use of the OS localtime_r() before going on...
sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 0
catchsql { SELECT datetime('now', 'localtime') }
} {1 {local time unavailable}}
do_test 2.2 {
- catchsql { SELECT datetime('now', 'utc') }
+ catchsql { SELECT datetime('2000-01-01', 'utc') }
} {1 {local time unavailable}}
sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 0