Fossil

Check-in [36eb0b4d28]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:The ymd= query parameter on /timeline understands the "Z" suffix on the date/time.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 36eb0b4d2864bcfba1b1ee3656e4a4bc663db994c8c0568f8b937a962a271665
User & Date: drh 2024-12-26 12:59:11.118
Context
2024-12-26
14:01
Correction and performance enhancement to ymd=. Add support for localtime to ym=. check-in: 376170abff user: drh tags: trunk
12:59
The ymd= query parameter on /timeline understands the "Z" suffix on the date/time. check-in: 36eb0b4d28 user: drh tags: trunk
12:03
Allow the optional "Z" zulu-time designator even on 8-character punctuationless date-time values. check-in: 3a3ce2fc65 user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/db.c.
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
  }
  return g.fTimeFormat==1;
}

/*
** Return true if Fossil is set to display times using the local timezone.
*/
int fossil_use_localtime(void){
  return fossil_ui_utctime()==0;
}

/*
** The toLocal() SQL function returns a string that is an argument to a
** date/time function that is appropriate for modifying the time for display.
** If UTC time display is selected, no modification occurs.  If local time







|







1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
  }
  return g.fTimeFormat==1;
}

/*
** Return true if Fossil is set to display times using the local timezone.
*/
int fossil_ui_localtime(void){
  return fossil_ui_utctime()==0;
}

/*
** The toLocal() SQL function returns a string that is an argument to a
** date/time function that is appropriate for modifying the time for display.
** If UTC time display is selected, no modification occurs.  If local time
Changes to src/timeline.c.
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323

1324
1325
1326
1327






1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
** Similar to fossil_expand_datetime()
**
** Add missing "-" characters into a date/time.  Examples:
**
**       20190419  =>  2019-04-19
**       201904    =>  2019-04
*/
const char *timeline_expand_datetime(const char *zIn){
  static char zEDate[20];
  static const char aPunct[] = { 0, 0, '-', '-', ' ', ':', ':' };
  int n = (int)strlen(zIn);
  int i, j;

  /* Only three forms allowed:

  **   (1)  YYYYMMDD
  **   (2)  YYYYMM
  **   (3)  YYYYWW
  */






  if( n!=8 && n!=6 ) return zIn;

  /* Every character must be a digit */
  for(i=0; fossil_isdigit(zIn[i]); i++){}
  if( i!=n ) return zIn;

  /* Expand the date */
  for(i=j=0; zIn[i]; i++){
    if( i>=4 && (i%2)==0 ){
      zEDate[j++] = aPunct[i/2];
    }
    zEDate[j++] = zIn[i];
  }
  zEDate[j] = 0;

  /* It looks like this may be a date.  Return it with punctuation added. */
  return zEDate;
}







|
|
<



|
>




>
>
>
>
>
>



|



|
<
|
<







1310
1311
1312
1313
1314
1315
1316
1317
1318

1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341

1342

1343
1344
1345
1346
1347
1348
1349
** Similar to fossil_expand_datetime()
**
** Add missing "-" characters into a date/time.  Examples:
**
**       20190419  =>  2019-04-19
**       201904    =>  2019-04
*/
const char *timeline_expand_datetime(const char *zIn, int *pbZulu){
  static char zEDate[16];

  int n = (int)strlen(zIn);
  int i, j;

  /* These forms are recognized:
  **
  **   (1)  YYYYMMDD
  **   (2)  YYYYMM
  **   (3)  YYYYWW
  */
  if( n && (zIn[n-1]=='Z' || zIn[n-1]=='z') ){
    n--;
    if( pbZulu ) *pbZulu = 1;
  }else{
    if( pbZulu ) *pbZulu = 0;
  }
  if( n!=8 && n!=6 ) return zIn;

  /* Every character must be a digit */
  for(i=0; i<n && fossil_isdigit(zIn[i]); i++){}
  if( i!=n ) return zIn;

  /* Expand the date */
  for(i=j=0; i<n; i++){

    if( j==4 || j==7 ) zEDate[j++] = '-';

    zEDate[j++] = zIn[i];
  }
  zEDate[j] = 0;

  /* It looks like this may be a date.  Return it with punctuation added. */
  return zEDate;
}
2370
2371
2372
2373
2374
2375
2376

2377
2378
2379
2380
2381
2382
2383
2384
      blob_append_sql(&cond, " AND event.objid IN cpnodes\n");
    }
    if( bisectLocal || zBisect!=0 ){
      blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog)\n");
    }
    if( zYearMonth ){
      char *zNext;

      zYearMonth = timeline_expand_datetime(zYearMonth);
      if( strlen(zYearMonth)>7 ){
        zYearMonth = mprintf("%.7s", zYearMonth);
      }
      if( db_int(0,"SELECT julianday('%q-01') IS NULL", zYearMonth) ){
        zYearMonth = db_text(0, "SELECT strftime('%%Y-%%m','now');");
      }
      zNext = db_text(0, "SELECT strftime('%%Y-%%m','%q-01','+1 month');",







>
|







2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
      blob_append_sql(&cond, " AND event.objid IN cpnodes\n");
    }
    if( bisectLocal || zBisect!=0 ){
      blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog)\n");
    }
    if( zYearMonth ){
      char *zNext;
      int bZulu = 0;
      zYearMonth = timeline_expand_datetime(zYearMonth, &bZulu);
      if( strlen(zYearMonth)>7 ){
        zYearMonth = mprintf("%.7s", zYearMonth);
      }
      if( db_int(0,"SELECT julianday('%q-01') IS NULL", zYearMonth) ){
        zYearMonth = db_text(0, "SELECT strftime('%%Y-%%m','now');");
      }
      zNext = db_text(0, "SELECT strftime('%%Y-%%m','%q-01','+1 month');",
2405
2406
2407
2408
2409
2410
2411

2412
2413
2414
2415
2416
2417
2418
2419
      fossil_free(zNext);
      blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
                      zYearMonth);
      nEntry = -1;
    }
    else if( zYearWeek ){
      char *z, *zNext;

      zYearWeek = timeline_expand_datetime(zYearWeek);
      z = db_text(0, "SELECT strftime('%%Y-%%W',%Q)", zYearWeek);
      if( z && z[0] ){
        zYearWeekStart = db_text(0, "SELECT date(%Q,'-6 days','weekday 1')",
                                 zYearWeek);
        zYearWeek = z;
      }else{
        if( strlen(zYearWeek)==7 ){







>
|







2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
      fossil_free(zNext);
      blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
                      zYearMonth);
      nEntry = -1;
    }
    else if( zYearWeek ){
      char *z, *zNext;
      int bZulu = 0;
      zYearWeek = timeline_expand_datetime(zYearWeek, &bZulu);
      z = db_text(0, "SELECT strftime('%%Y-%%W',%Q)", zYearWeek);
      if( z && z[0] ){
        zYearWeekStart = db_text(0, "SELECT date(%Q,'-6 days','weekday 1')",
                                 zYearWeek);
        zYearWeek = z;
      }else{
        if( strlen(zYearWeek)==7 ){
2452
2453
2454
2455
2456
2457
2458


2459
2460
2461
2462
2463
2464

2465
2466
2467

2468
2469


2470
2471
2472
2473
2474

2475
2476
2477

2478
2479


2480
2481
2482
2483

2484
2485
2486



2487
2488
2489
2490
2491
2492
2493
      fossil_free(zNext);
      blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
                   zYearWeek);
      nEntry = -1;
    }
    else if( zDay ){
      char *zNext;


      zDay = timeline_expand_datetime(zDay);
      zDay = db_text(0, "SELECT date(%Q)", zDay);
      if( zDay==0 || zDay[0]==0 ){
        zDay = db_text(0, "SELECT date('now')");
      }
      zNext = db_text(0, "SELECT date(%Q,'+1 day');", zDay);

      if( db_int(0,
          "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
          " WHERE blob.rid=event.objid AND mtime>=julianday(%Q)%s)",

          zNext, blob_sql_text(&cond))
      ){


        zNewerButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
        zNewerButtonLabel = "Following day";
      }
      fossil_free(zNext);
      zNext = db_text(0, "SELECT date(%Q,'-1 day');", zDay);

      if( db_int(0,
          "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
          " WHERE blob.rid=event.objid AND mtime<julianday(%Q)%s)",

          zDay, blob_sql_text(&cond))
      ){


        zOlderButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
        zOlderButtonLabel = "Previous day";
      }
      fossil_free(zNext);

      blob_append_sql(&cond, " AND %Q=date(event.mtime) ",
                   zDay);
      nEntry = -1;



    }
    else if( zNDays ){
      nDays = atoi(zNDays);
      if( nDays<1 ) nDays = 1;
      blob_append_sql(&cond, " AND event.mtime>=julianday('now','-%d days') ",
                      nDays);
      nEntry = -1;







>
>
|




<
>


|
>
|

>
>


<
|
<
>


|
>
|

>
>


<
|
>
|
<

>
>
>







2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471

2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482

2483

2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494

2495
2496
2497

2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
      fossil_free(zNext);
      blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
                   zYearWeek);
      nEntry = -1;
    }
    else if( zDay ){
      char *zNext;
      int bZulu = 0;
      const char *zTZMod;
      zDay = timeline_expand_datetime(zDay, &bZulu);
      zDay = db_text(0, "SELECT date(%Q)", zDay);
      if( zDay==0 || zDay[0]==0 ){
        zDay = db_text(0, "SELECT date('now')");
      }

      zTZMod = (bZulu==0 && fossil_ui_localtime()) ? "localtime" : "utc";
      if( db_int(0,
          "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
          " WHERE blob.rid=event.objid"
          "   AND mtime>=julianday(%Q,'+1 day',%Q)%s)",
          zDay, zTZMod, blob_sql_text(&cond))
      ){
        zNext = db_text(0,"SELECT strftime('%%Y%%m%%d%q',%Q,'+1 day');",
                        &"Z"[!bZulu], zDay);
        zNewerButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
        zNewerButtonLabel = "Following day";

        fossil_free(zNext);

      }
      if( db_int(0,
          "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
          " WHERE blob.rid=event.objid"
          "   AND mtime<julianday(%Q,'-1 day',%Q)%s)",
          zDay, zTZMod, blob_sql_text(&cond))
      ){
        zNext = db_text(0,"SELECT strftime('%%Y%%m%%d%q',%Q,'-1 day');",
                        &"Z"[!bZulu], zDay);
        zOlderButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
        zOlderButtonLabel = "Previous day";

        fossil_free(zNext);
      }
      blob_append_sql(&cond, " AND %Q=date(event.mtime,%Q) ", zDay, zTZMod);

      nEntry = -1;
      if( fossil_ui_localtime() && bZulu ){
        zDay = mprintf("%zZ", zDay); /* Add Z suffix to day for the title */
      }
    }
    else if( zNDays ){
      nDays = atoi(zNDays);
      if( nDays<1 ) nDays = 1;
      blob_append_sql(&cond, " AND event.mtime>=julianday('now','-%d days') ",
                      nDays);
      nEntry = -1;
3615
3616
3617
3618
3619
3620
3621

3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
void thisdayinhistory_page(void){
  static int aYearsAgo[] = { 1, 2, 3, 4, 5, 10, 15, 20, 30, 40, 50, 75, 100 };
  const char *zToday;
  char *zStartOfProject;
  int i;
  Stmt q;
  char *z;


  login_check_credentials();
  if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum) ){
    login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
    return;
  }
  style_set_current_feature("timeline");
  style_header("Today In History");
  zToday = (char*)P("today");
  if( zToday ){
    zToday = timeline_expand_datetime(zToday);
    if( !fossil_isdate(zToday) ) zToday = 0;
  }
  if( zToday==0 ){
    zToday = db_text(0, "SELECT date('now',toLocal())");
  }
  @ <h1>This Day In History For %h(zToday)</h1>
  z = db_text(0, "SELECT date(%Q,'-1 day')", zToday);







>










|







3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
void thisdayinhistory_page(void){
  static int aYearsAgo[] = { 1, 2, 3, 4, 5, 10, 15, 20, 30, 40, 50, 75, 100 };
  const char *zToday;
  char *zStartOfProject;
  int i;
  Stmt q;
  char *z;
  int bZulu = 0;

  login_check_credentials();
  if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum) ){
    login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
    return;
  }
  style_set_current_feature("timeline");
  style_header("Today In History");
  zToday = (char*)P("today");
  if( zToday ){
    zToday = timeline_expand_datetime(zToday, &bZulu);
    if( !fossil_isdate(zToday) ) zToday = 0;
  }
  if( zToday==0 ){
    zToday = db_text(0, "SELECT date('now',toLocal())");
  }
  @ <h1>This Day In History For %h(zToday)</h1>
  z = db_text(0, "SELECT date(%Q,'-1 day')", zToday);