Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | closes [cd25761979]: `clock format` and `clock add` will accept `now` as clock value (value `-now` retained to compat reasons to earlier versions and tclclockmod, undocumented at the moment) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | core-8-branch |
Files: | files | file ages | folders |
SHA3-256: |
f602e32fc37910d1f03a30f3722c1a0b |
User & Date: | sebres 2024-07-28 19:44:23 |
Original Comment: | closes [cd25761979]: `clock format` and `clock add` will accept `now` as clock value (value `-now` retained to compat reasons to earlier versions and tclclockmod, undocummented at the moment) |
References
2024-07-28
| ||
19:52 | • Closed ticket [cd25761979]: clock command - "now" vs "-now" plus 6 other changes artifact: 5e62e0bbde user: sebres | |
Context
2024-07-29
| ||
08:08 | Fix [7d5f1c1308] - zipfs mkzip error on Windows dotfiles check-in: c32b19f04e user: apnadkarni tags: core-8-branch | |
2024-07-28
| ||
19:47 | merge 8.7 check-in: 9dff0d22e1 user: sebres tags: trunk, main | |
19:44 | closes [cd25761979]: `clock format` and `clock add` will accept `now` as clock value (value `-now` r... check-in: f602e32fc3 user: sebres tags: core-8-branch | |
19:25 | merge 8.6 check-in: fec9d3c764 user: sebres tags: core-8-branch | |
Changes
Changes to doc/clock.n.
︙ | ︙ | |||
83 84 85 86 87 88 89 | 1 January 1970, 00:00 UTC. Note that the count of seconds does not include any leap seconds; seconds are counted as if each UTC day has exactly 86400 seconds. Tcl responds to leap seconds by speeding or slowing its clock by a tiny fraction for some minutes until it is back in sync with UTC; its data model does not represent minutes that have 59 or 61 seconds. .TP | | | | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 1 January 1970, 00:00 UTC. Note that the count of seconds does not include any leap seconds; seconds are counted as if each UTC day has exactly 86400 seconds. Tcl responds to leap seconds by speeding or slowing its clock by a tiny fraction for some minutes until it is back in sync with UTC; its data model does not represent minutes that have 59 or 61 seconds. .TP \fI\now\fR Instead of \fItimeVal\fR a non-integer option \fI\now\fR can be used as replacement for today, which is simply interpolated to the runt-time as value of \fBclock seconds\fR. For example: .sp \fBclock format now -f %a; # current day of the week\fR .sp \fBclock add now 1 month; # next month\fR .TP \fIunit\fR One of the words, \fBseconds\fR, \fBminutes\fR, \fBhours\fR, \fBdays\fR, \fBweekdays\fR, \fBweeks\fR, \fBmonths\fR, or \fByears\fR. Used in conjunction with \fIcount\fR to identify an interval of time, for example, \fI3 seconds\fR or \fI1 year\fR. .SS "OPTIONS" |
︙ | ︙ |
Changes to generic/tclClock.c.
︙ | ︙ | |||
3415 3416 3417 3418 3419 3420 3421 | } /* Base (by scan or add) or clock value (by format) */ if (opts->baseObj != NULL) { Tcl_Obj *baseObj = opts->baseObj; | | > > | | | | | > > | 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 | } /* Base (by scan or add) or clock value (by format) */ if (opts->baseObj != NULL) { Tcl_Obj *baseObj = opts->baseObj; /* bypass integer recognition if looks like "now" or "-now" */ if ((baseObj->bytes && ((baseObj->length == 3 && baseObj->bytes[0] == 'n') || (baseObj->length == 4 && baseObj->bytes[1] == 'n'))) || TclGetWideIntFromObj(NULL, baseObj, &baseVal) != TCL_OK) { /* we accept "now" and "-now" as current date-time */ static const char *const nowOpts[] = { "now", "-now", NULL }; int idx; if (Tcl_GetIndexFromObj(NULL, baseObj, nowOpts, "seconds", TCL_EXACT, &idx) == TCL_OK) { goto baseNow; } if (TclHasInternalRep(baseObj, &tclBignumType)) { goto baseOverflow; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad seconds \"%s\": must be now or integer", TclGetString(baseObj))); i = baseIdx; goto badOption; } /* * Seconds could be an unsigned number that overflowed. Make sure * that it isn't. Additionally it may be too complex to calculate * julianday etc (forwards/backwards) by too large/small values, thus |
︙ | ︙ | |||
3525 3526 3527 3528 3529 3530 3531 | ClockFormatObjCmd( void *clientData, /* Client data containing literal pool */ Tcl_Interp *interp, /* Tcl interpreter */ int objc, /* Parameter count */ Tcl_Obj *const objv[]) /* Parameter values */ { ClockClientData *dataPtr = (ClockClientData *)clientData; | | | 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 | ClockFormatObjCmd( void *clientData, /* Client data containing literal pool */ Tcl_Interp *interp, /* Tcl interpreter */ int objc, /* Parameter count */ Tcl_Obj *const objv[]) /* Parameter values */ { ClockClientData *dataPtr = (ClockClientData *)clientData; static const char *syntax = "clock format clockval|now " "?-format string? " "?-gmt boolean? " "?-locale LOCALE? ?-timezone ZONE?"; int ret; ClockFmtScnCmdArgs opts; /* Format, locale, timezone and base */ DateFormat dateFmt; /* Common structure used for formatting */ |
︙ | ︙ | |||
4359 4360 4361 4362 4363 4364 4365 | int ClockAddObjCmd( void *clientData, /* Client data containing literal pool */ Tcl_Interp *interp, /* Tcl interpreter */ int objc, /* Parameter count */ Tcl_Obj *const objv[]) /* Parameter values */ { | | | 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 | int ClockAddObjCmd( void *clientData, /* Client data containing literal pool */ Tcl_Interp *interp, /* Tcl interpreter */ int objc, /* Parameter count */ Tcl_Obj *const objv[]) /* Parameter values */ { static const char *syntax = "clock add clockval|now ?number units?..." "?-gmt boolean? " "?-locale LOCALE? ?-timezone ZONE?"; ClockClientData *dataPtr = (ClockClientData *)clientData; int ret; ClockFmtScnCmdArgs opts; /* Format, locale, timezone and base */ DateInfo yy; /* Common structure used for parsing */ DateInfo *info = &yy; |
︙ | ︙ |
Changes to tests/clock.test.
︙ | ︙ | |||
279 280 281 282 283 284 285 | set i [interp create]; # because clock can be used somewhere, test it in new interp: } -body { $i eval { lappend ret ens:[namespace ensemble exists ::clock] clock seconds; # init ensemble (but not yet stubs, loading of clock.tcl retarded) lappend ret ens:[namespace ensemble exists ::clock] lappend ret stubs:[expr {[namespace which -command ::tcl::clock::GetSystemTimeZone] ne ""}] | | | | | | | 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | set i [interp create]; # because clock can be used somewhere, test it in new interp: } -body { $i eval { lappend ret ens:[namespace ensemble exists ::clock] clock seconds; # init ensemble (but not yet stubs, loading of clock.tcl retarded) lappend ret ens:[namespace ensemble exists ::clock] lappend ret stubs:[expr {[namespace which -command ::tcl::clock::GetSystemTimeZone] ne ""}] clock format now; # clock.tcl stubs expected lappend ret stubs:[expr {[namespace which -command ::tcl::clock::GetSystemTimeZone] ne ""}] } } -cleanup { interp delete $i } -result {ens:1 ens:1 stubs:0 stubs:1} test clock-0.1a "initial: safe interpreter shares clock command with parent" -setup { set i [interp create] $i eval {set sci [interp create -safe]} } -body { $i eval { lappend ret ens:[namespace ensemble exists ::clock] $sci eval { clock seconds }; # init ensemble (but not yet stubs, loading of clock.tcl retarded) lappend ret ens:[namespace ensemble exists ::clock] lappend ret stubs:[expr {[namespace which -command ::tcl::clock::GetSystemTimeZone] ne ""}] $sci eval { clock format now }; # clock.tcl stubs expected lappend ret stubs:[expr {[namespace which -command ::tcl::clock::GetSystemTimeZone] ne ""}] } } -cleanup { interp delete $i } -result {ens:1 ens:1 stubs:0 stubs:1} test clock-0.2 "initial: loading of format/locale does not overwrite interp state (errorInfo)" -setup { # be sure - we have no cached locale/msgcat, etc: if {[namespace which -command ::tcl::clock::ClearCaches] ne ""} { ::tcl::clock::ClearCaches } } -body { if {[catch { return -level 0 -code error -errorcode {EXPERR TEST-ERROR} -errorinfo "ERROR expected error" test }]} { clock format now -locale de; # should not overwrite error code/info list $::errorCode $::errorInfo } } -result {{EXPERR TEST-ERROR} {ERROR expected error}} # Test some of the basics of [clock format] set syntax "clockval|now ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?" test clock-1.0 "clock format - wrong # args" { list [catch {clock format} msg] $msg $::errorCode } [subst {1 {wrong # args: should be "clock format $syntax"} {CLOCK wrongNumArgs}}] test clock-1.0.1 "clock format - wrong # args (compiled ensemble with invalid syntax)" { list [catch {clock format 0 -too-few-options-4-test} msg] $msg $::errorCode } [subst {1 {wrong # args: should be "clock format $syntax"} {CLOCK wrongNumArgs}}] test clock-1.1 "clock format - bad time" { list [catch {clock format foo} msg opt] $msg [dict getd $opt -errorcode {}] } {1 {bad seconds "foo": must be now or integer} {CLOCK badOption foo}} test clock-1.2 "clock format - bad gmt val" { list [catch {clock format 0 -gmt foo} msg] $msg } {1 {expected boolean value but got "foo"}} test clock-1.3 "clock format - empty val" { clock format 0 -gmt 1 -format "" |
︙ | ︙ | |||
363 364 365 366 367 368 369 | clock format 0 -g true -f "%Y-%m-%d" } 1970-01-01 test clock-1.7.1 "clock format - command abbreviations (compat regression test)" { clock f 0 -g 1 -f "%Y-%m-%d" } 1970-01-01 | | | | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | clock format 0 -g true -f "%Y-%m-%d" } 1970-01-01 test clock-1.7.1 "clock format - command abbreviations (compat regression test)" { clock f 0 -g 1 -f "%Y-%m-%d" } 1970-01-01 test clock-1.8 "clock format now" { # give one second more for test (if on boundary of the current second): set n [clock format [clock seconds] -g 1 -f "%s"] expr {[clock format now -g 1 -f "%s"] in [list $n [incr n]]} } 1 test clock-1.9 "clock arguments: option doubly present" { list [catch {clock format 0 -gmt 1 -gmt 0} result] $result } {1 {bad option "-gmt": doubly present}} test clock-1.10 {clock format: text with token (bug [a858d95f4bfddafb])} { |
︙ | ︙ | |||
18700 18701 18702 18703 18704 18705 18706 | test clock-6.8 {input of seconds} { clock scan {9223372036854775807} -format %s -gmt true } 9223372036854775807 test clock-6.8b "clock scan - bad base" { list [catch {clock scan "" -base foo -gmt 1} msg opt] $msg [dict getd $opt -errorcode {}] | | | 18700 18701 18702 18703 18704 18705 18706 18707 18708 18709 18710 18711 18712 18713 18714 | test clock-6.8 {input of seconds} { clock scan {9223372036854775807} -format %s -gmt true } 9223372036854775807 test clock-6.8b "clock scan - bad base" { list [catch {clock scan "" -base foo -gmt 1} msg opt] $msg [dict getd $opt -errorcode {}] } {1 {bad seconds "foo": must be now or integer} {CLOCK badOption foo}} test clock-6.9 {input of seconds - overflow} { list [catch {clock scan -9223372036854775809 -format %s -gmt true} result opt] $result [dict getd $opt -errorcode ""] } {1 {integer value too large to represent} {CLOCK dateTooLarge}} test clock-6.10 {input of seconds - overflow} { list [catch {clock scan 9223372036854775808 -format %s -gmt true} result opt] $result [dict getd $opt -errorcode ""] } {1 {integer value too large to represent} {CLOCK dateTooLarge}} |
︙ | ︙ |