Fossil SCM

The ymd= query parameter on /timeline understands the "Z" suffix on the date/time.

drh 2024-12-26 12:59 trunk
Commit 36eb0b4d2864bcfba1b1ee3656e4a4bc663db994c8c0568f8b937a962a271665
2 files changed +1 -1 +52 -36
+1 -1
--- src/db.c
+++ src/db.c
@@ -1385,11 +1385,11 @@
13851385
}
13861386
13871387
/*
13881388
** Return true if Fossil is set to display times using the local timezone.
13891389
*/
1390
-int fossil_use_localtime(void){
1390
+int fossil_ui_localtime(void){
13911391
return fossil_ui_utctime()==0;
13921392
}
13931393
13941394
/*
13951395
** The toLocal() SQL function returns a string that is an argument to a
13961396
--- src/db.c
+++ src/db.c
@@ -1385,11 +1385,11 @@
1385 }
1386
1387 /*
1388 ** Return true if Fossil is set to display times using the local timezone.
1389 */
1390 int fossil_use_localtime(void){
1391 return fossil_ui_utctime()==0;
1392 }
1393
1394 /*
1395 ** The toLocal() SQL function returns a string that is an argument to a
1396
--- src/db.c
+++ src/db.c
@@ -1385,11 +1385,11 @@
1385 }
1386
1387 /*
1388 ** Return true if Fossil is set to display times using the local timezone.
1389 */
1390 int fossil_ui_localtime(void){
1391 return fossil_ui_utctime()==0;
1392 }
1393
1394 /*
1395 ** The toLocal() SQL function returns a string that is an argument to a
1396
+52 -36
--- src/timeline.c
+++ src/timeline.c
@@ -1312,32 +1312,36 @@
13121312
** Add missing "-" characters into a date/time. Examples:
13131313
**
13141314
** 20190419 => 2019-04-19
13151315
** 201904 => 2019-04
13161316
*/
1317
-const char *timeline_expand_datetime(const char *zIn){
1318
- static char zEDate[20];
1319
- static const char aPunct[] = { 0, 0, '-', '-', ' ', ':', ':' };
1317
+const char *timeline_expand_datetime(const char *zIn, int *pbZulu){
1318
+ static char zEDate[16];
13201319
int n = (int)strlen(zIn);
13211320
int i, j;
13221321
1323
- /* Only three forms allowed:
1322
+ /* These forms are recognized:
1323
+ **
13241324
** (1) YYYYMMDD
13251325
** (2) YYYYMM
13261326
** (3) YYYYWW
13271327
*/
1328
+ if( n && (zIn[n-1]=='Z' || zIn[n-1]=='z') ){
1329
+ n--;
1330
+ if( pbZulu ) *pbZulu = 1;
1331
+ }else{
1332
+ if( pbZulu ) *pbZulu = 0;
1333
+ }
13281334
if( n!=8 && n!=6 ) return zIn;
13291335
13301336
/* Every character must be a digit */
1331
- for(i=0; fossil_isdigit(zIn[i]); i++){}
1337
+ for(i=0; i<n && fossil_isdigit(zIn[i]); i++){}
13321338
if( i!=n ) return zIn;
13331339
13341340
/* Expand the date */
1335
- for(i=j=0; zIn[i]; i++){
1336
- if( i>=4 && (i%2)==0 ){
1337
- zEDate[j++] = aPunct[i/2];
1338
- }
1341
+ for(i=j=0; i<n; i++){
1342
+ if( j==4 || j==7 ) zEDate[j++] = '-';
13391343
zEDate[j++] = zIn[i];
13401344
}
13411345
zEDate[j] = 0;
13421346
13431347
/* It looks like this may be a date. Return it with punctuation added. */
@@ -2372,11 +2376,12 @@
23722376
if( bisectLocal || zBisect!=0 ){
23732377
blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog)\n");
23742378
}
23752379
if( zYearMonth ){
23762380
char *zNext;
2377
- zYearMonth = timeline_expand_datetime(zYearMonth);
2381
+ int bZulu = 0;
2382
+ zYearMonth = timeline_expand_datetime(zYearMonth, &bZulu);
23782383
if( strlen(zYearMonth)>7 ){
23792384
zYearMonth = mprintf("%.7s", zYearMonth);
23802385
}
23812386
if( db_int(0,"SELECT julianday('%q-01') IS NULL", zYearMonth) ){
23822387
zYearMonth = db_text(0, "SELECT strftime('%%Y-%%m','now');");
@@ -2407,11 +2412,12 @@
24072412
zYearMonth);
24082413
nEntry = -1;
24092414
}
24102415
else if( zYearWeek ){
24112416
char *z, *zNext;
2412
- zYearWeek = timeline_expand_datetime(zYearWeek);
2417
+ int bZulu = 0;
2418
+ zYearWeek = timeline_expand_datetime(zYearWeek, &bZulu);
24132419
z = db_text(0, "SELECT strftime('%%Y-%%W',%Q)", zYearWeek);
24142420
if( z && z[0] ){
24152421
zYearWeekStart = db_text(0, "SELECT date(%Q,'-6 days','weekday 1')",
24162422
zYearWeek);
24172423
zYearWeek = z;
@@ -2454,38 +2460,47 @@
24542460
zYearWeek);
24552461
nEntry = -1;
24562462
}
24572463
else if( zDay ){
24582464
char *zNext;
2459
- zDay = timeline_expand_datetime(zDay);
2465
+ int bZulu = 0;
2466
+ const char *zTZMod;
2467
+ zDay = timeline_expand_datetime(zDay, &bZulu);
24602468
zDay = db_text(0, "SELECT date(%Q)", zDay);
24612469
if( zDay==0 || zDay[0]==0 ){
24622470
zDay = db_text(0, "SELECT date('now')");
24632471
}
2464
- zNext = db_text(0, "SELECT date(%Q,'+1 day');", zDay);
2465
- if( db_int(0,
2466
- "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
2467
- " WHERE blob.rid=event.objid AND mtime>=julianday(%Q)%s)",
2468
- zNext, blob_sql_text(&cond))
2469
- ){
2470
- zNewerButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
2471
- zNewerButtonLabel = "Following day";
2472
- }
2473
- fossil_free(zNext);
2474
- zNext = db_text(0, "SELECT date(%Q,'-1 day');", zDay);
2475
- if( db_int(0,
2476
- "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
2477
- " WHERE blob.rid=event.objid AND mtime<julianday(%Q)%s)",
2478
- zDay, blob_sql_text(&cond))
2479
- ){
2480
- zOlderButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
2481
- zOlderButtonLabel = "Previous day";
2482
- }
2483
- fossil_free(zNext);
2484
- blob_append_sql(&cond, " AND %Q=date(event.mtime) ",
2485
- zDay);
2486
- nEntry = -1;
2472
+ zTZMod = (bZulu==0 && fossil_ui_localtime()) ? "localtime" : "utc";
2473
+ if( db_int(0,
2474
+ "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
2475
+ " WHERE blob.rid=event.objid"
2476
+ " AND mtime>=julianday(%Q,'+1 day',%Q)%s)",
2477
+ zDay, zTZMod, blob_sql_text(&cond))
2478
+ ){
2479
+ zNext = db_text(0,"SELECT strftime('%%Y%%m%%d%q',%Q,'+1 day');",
2480
+ &"Z"[!bZulu], zDay);
2481
+ zNewerButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
2482
+ zNewerButtonLabel = "Following day";
2483
+ fossil_free(zNext);
2484
+ }
2485
+ if( db_int(0,
2486
+ "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
2487
+ " WHERE blob.rid=event.objid"
2488
+ " AND mtime<julianday(%Q,'-1 day',%Q)%s)",
2489
+ zDay, zTZMod, blob_sql_text(&cond))
2490
+ ){
2491
+ zNext = db_text(0,"SELECT strftime('%%Y%%m%%d%q',%Q,'-1 day');",
2492
+ &"Z"[!bZulu], zDay);
2493
+ zOlderButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
2494
+ zOlderButtonLabel = "Previous day";
2495
+ fossil_free(zNext);
2496
+ }
2497
+ blob_append_sql(&cond, " AND %Q=date(event.mtime,%Q) ", zDay, zTZMod);
2498
+ nEntry = -1;
2499
+ if( fossil_ui_localtime() && bZulu ){
2500
+ zDay = mprintf("%zZ", zDay); /* Add Z suffix to day for the title */
2501
+ }
24872502
}
24882503
else if( zNDays ){
24892504
nDays = atoi(zNDays);
24902505
if( nDays<1 ) nDays = 1;
24912506
blob_append_sql(&cond, " AND event.mtime>=julianday('now','-%d days') ",
@@ -3617,10 +3632,11 @@
36173632
const char *zToday;
36183633
char *zStartOfProject;
36193634
int i;
36203635
Stmt q;
36213636
char *z;
3637
+ int bZulu = 0;
36223638
36233639
login_check_credentials();
36243640
if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum) ){
36253641
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
36263642
return;
@@ -3627,11 +3643,11 @@
36273643
}
36283644
style_set_current_feature("timeline");
36293645
style_header("Today In History");
36303646
zToday = (char*)P("today");
36313647
if( zToday ){
3632
- zToday = timeline_expand_datetime(zToday);
3648
+ zToday = timeline_expand_datetime(zToday, &bZulu);
36333649
if( !fossil_isdate(zToday) ) zToday = 0;
36343650
}
36353651
if( zToday==0 ){
36363652
zToday = db_text(0, "SELECT date('now',toLocal())");
36373653
}
36383654
--- src/timeline.c
+++ src/timeline.c
@@ -1312,32 +1312,36 @@
1312 ** Add missing "-" characters into a date/time. Examples:
1313 **
1314 ** 20190419 => 2019-04-19
1315 ** 201904 => 2019-04
1316 */
1317 const char *timeline_expand_datetime(const char *zIn){
1318 static char zEDate[20];
1319 static const char aPunct[] = { 0, 0, '-', '-', ' ', ':', ':' };
1320 int n = (int)strlen(zIn);
1321 int i, j;
1322
1323 /* Only three forms allowed:
 
1324 ** (1) YYYYMMDD
1325 ** (2) YYYYMM
1326 ** (3) YYYYWW
1327 */
 
 
 
 
 
 
1328 if( n!=8 && n!=6 ) return zIn;
1329
1330 /* Every character must be a digit */
1331 for(i=0; fossil_isdigit(zIn[i]); i++){}
1332 if( i!=n ) return zIn;
1333
1334 /* Expand the date */
1335 for(i=j=0; zIn[i]; i++){
1336 if( i>=4 && (i%2)==0 ){
1337 zEDate[j++] = aPunct[i/2];
1338 }
1339 zEDate[j++] = zIn[i];
1340 }
1341 zEDate[j] = 0;
1342
1343 /* It looks like this may be a date. Return it with punctuation added. */
@@ -2372,11 +2376,12 @@
2372 if( bisectLocal || zBisect!=0 ){
2373 blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog)\n");
2374 }
2375 if( zYearMonth ){
2376 char *zNext;
2377 zYearMonth = timeline_expand_datetime(zYearMonth);
 
2378 if( strlen(zYearMonth)>7 ){
2379 zYearMonth = mprintf("%.7s", zYearMonth);
2380 }
2381 if( db_int(0,"SELECT julianday('%q-01') IS NULL", zYearMonth) ){
2382 zYearMonth = db_text(0, "SELECT strftime('%%Y-%%m','now');");
@@ -2407,11 +2412,12 @@
2407 zYearMonth);
2408 nEntry = -1;
2409 }
2410 else if( zYearWeek ){
2411 char *z, *zNext;
2412 zYearWeek = timeline_expand_datetime(zYearWeek);
 
2413 z = db_text(0, "SELECT strftime('%%Y-%%W',%Q)", zYearWeek);
2414 if( z && z[0] ){
2415 zYearWeekStart = db_text(0, "SELECT date(%Q,'-6 days','weekday 1')",
2416 zYearWeek);
2417 zYearWeek = z;
@@ -2454,38 +2460,47 @@
2454 zYearWeek);
2455 nEntry = -1;
2456 }
2457 else if( zDay ){
2458 char *zNext;
2459 zDay = timeline_expand_datetime(zDay);
 
 
2460 zDay = db_text(0, "SELECT date(%Q)", zDay);
2461 if( zDay==0 || zDay[0]==0 ){
2462 zDay = db_text(0, "SELECT date('now')");
2463 }
2464 zNext = db_text(0, "SELECT date(%Q,'+1 day');", zDay);
2465 if( db_int(0,
2466 "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
2467 " WHERE blob.rid=event.objid AND mtime>=julianday(%Q)%s)",
2468 zNext, blob_sql_text(&cond))
2469 ){
2470 zNewerButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
2471 zNewerButtonLabel = "Following day";
2472 }
2473 fossil_free(zNext);
2474 zNext = db_text(0, "SELECT date(%Q,'-1 day');", zDay);
2475 if( db_int(0,
2476 "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
2477 " WHERE blob.rid=event.objid AND mtime<julianday(%Q)%s)",
2478 zDay, blob_sql_text(&cond))
2479 ){
2480 zOlderButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
2481 zOlderButtonLabel = "Previous day";
2482 }
2483 fossil_free(zNext);
2484 blob_append_sql(&cond, " AND %Q=date(event.mtime) ",
2485 zDay);
2486 nEntry = -1;
 
 
 
 
 
 
 
2487 }
2488 else if( zNDays ){
2489 nDays = atoi(zNDays);
2490 if( nDays<1 ) nDays = 1;
2491 blob_append_sql(&cond, " AND event.mtime>=julianday('now','-%d days') ",
@@ -3617,10 +3632,11 @@
3617 const char *zToday;
3618 char *zStartOfProject;
3619 int i;
3620 Stmt q;
3621 char *z;
 
3622
3623 login_check_credentials();
3624 if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum) ){
3625 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
3626 return;
@@ -3627,11 +3643,11 @@
3627 }
3628 style_set_current_feature("timeline");
3629 style_header("Today In History");
3630 zToday = (char*)P("today");
3631 if( zToday ){
3632 zToday = timeline_expand_datetime(zToday);
3633 if( !fossil_isdate(zToday) ) zToday = 0;
3634 }
3635 if( zToday==0 ){
3636 zToday = db_text(0, "SELECT date('now',toLocal())");
3637 }
3638
--- src/timeline.c
+++ src/timeline.c
@@ -1312,32 +1312,36 @@
1312 ** Add missing "-" characters into a date/time. Examples:
1313 **
1314 ** 20190419 => 2019-04-19
1315 ** 201904 => 2019-04
1316 */
1317 const char *timeline_expand_datetime(const char *zIn, int *pbZulu){
1318 static char zEDate[16];
 
1319 int n = (int)strlen(zIn);
1320 int i, j;
1321
1322 /* These forms are recognized:
1323 **
1324 ** (1) YYYYMMDD
1325 ** (2) YYYYMM
1326 ** (3) YYYYWW
1327 */
1328 if( n && (zIn[n-1]=='Z' || zIn[n-1]=='z') ){
1329 n--;
1330 if( pbZulu ) *pbZulu = 1;
1331 }else{
1332 if( pbZulu ) *pbZulu = 0;
1333 }
1334 if( n!=8 && n!=6 ) return zIn;
1335
1336 /* Every character must be a digit */
1337 for(i=0; i<n && fossil_isdigit(zIn[i]); i++){}
1338 if( i!=n ) return zIn;
1339
1340 /* Expand the date */
1341 for(i=j=0; i<n; i++){
1342 if( j==4 || j==7 ) zEDate[j++] = '-';
 
 
1343 zEDate[j++] = zIn[i];
1344 }
1345 zEDate[j] = 0;
1346
1347 /* It looks like this may be a date. Return it with punctuation added. */
@@ -2372,11 +2376,12 @@
2376 if( bisectLocal || zBisect!=0 ){
2377 blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog)\n");
2378 }
2379 if( zYearMonth ){
2380 char *zNext;
2381 int bZulu = 0;
2382 zYearMonth = timeline_expand_datetime(zYearMonth, &bZulu);
2383 if( strlen(zYearMonth)>7 ){
2384 zYearMonth = mprintf("%.7s", zYearMonth);
2385 }
2386 if( db_int(0,"SELECT julianday('%q-01') IS NULL", zYearMonth) ){
2387 zYearMonth = db_text(0, "SELECT strftime('%%Y-%%m','now');");
@@ -2407,11 +2412,12 @@
2412 zYearMonth);
2413 nEntry = -1;
2414 }
2415 else if( zYearWeek ){
2416 char *z, *zNext;
2417 int bZulu = 0;
2418 zYearWeek = timeline_expand_datetime(zYearWeek, &bZulu);
2419 z = db_text(0, "SELECT strftime('%%Y-%%W',%Q)", zYearWeek);
2420 if( z && z[0] ){
2421 zYearWeekStart = db_text(0, "SELECT date(%Q,'-6 days','weekday 1')",
2422 zYearWeek);
2423 zYearWeek = z;
@@ -2454,38 +2460,47 @@
2460 zYearWeek);
2461 nEntry = -1;
2462 }
2463 else if( zDay ){
2464 char *zNext;
2465 int bZulu = 0;
2466 const char *zTZMod;
2467 zDay = timeline_expand_datetime(zDay, &bZulu);
2468 zDay = db_text(0, "SELECT date(%Q)", zDay);
2469 if( zDay==0 || zDay[0]==0 ){
2470 zDay = db_text(0, "SELECT date('now')");
2471 }
2472 zTZMod = (bZulu==0 && fossil_ui_localtime()) ? "localtime" : "utc";
2473 if( db_int(0,
2474 "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
2475 " WHERE blob.rid=event.objid"
2476 " AND mtime>=julianday(%Q,'+1 day',%Q)%s)",
2477 zDay, zTZMod, blob_sql_text(&cond))
2478 ){
2479 zNext = db_text(0,"SELECT strftime('%%Y%%m%%d%q',%Q,'+1 day');",
2480 &"Z"[!bZulu], zDay);
2481 zNewerButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
2482 zNewerButtonLabel = "Following day";
2483 fossil_free(zNext);
2484 }
2485 if( db_int(0,
2486 "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
2487 " WHERE blob.rid=event.objid"
2488 " AND mtime<julianday(%Q,'-1 day',%Q)%s)",
2489 zDay, zTZMod, blob_sql_text(&cond))
2490 ){
2491 zNext = db_text(0,"SELECT strftime('%%Y%%m%%d%q',%Q,'-1 day');",
2492 &"Z"[!bZulu], zDay);
2493 zOlderButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
2494 zOlderButtonLabel = "Previous day";
2495 fossil_free(zNext);
2496 }
2497 blob_append_sql(&cond, " AND %Q=date(event.mtime,%Q) ", zDay, zTZMod);
2498 nEntry = -1;
2499 if( fossil_ui_localtime() && bZulu ){
2500 zDay = mprintf("%zZ", zDay); /* Add Z suffix to day for the title */
2501 }
2502 }
2503 else if( zNDays ){
2504 nDays = atoi(zNDays);
2505 if( nDays<1 ) nDays = 1;
2506 blob_append_sql(&cond, " AND event.mtime>=julianday('now','-%d days') ",
@@ -3617,10 +3632,11 @@
3632 const char *zToday;
3633 char *zStartOfProject;
3634 int i;
3635 Stmt q;
3636 char *z;
3637 int bZulu = 0;
3638
3639 login_check_credentials();
3640 if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum) ){
3641 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
3642 return;
@@ -3627,11 +3643,11 @@
3643 }
3644 style_set_current_feature("timeline");
3645 style_header("Today In History");
3646 zToday = (char*)P("today");
3647 if( zToday ){
3648 zToday = timeline_expand_datetime(zToday, &bZulu);
3649 if( !fossil_isdate(zToday) ) zToday = 0;
3650 }
3651 if( zToday==0 ){
3652 zToday = db_text(0, "SELECT date('now',toLocal())");
3653 }
3654

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button