TIP 690: Make "clock scan -valid 1" the default

Login
Author:		Jan Nijtmans <[email protected]>, Rolf Ade <[email protected]>
State:		Final
Type:		Project
Vote:		Done
Created:	20-03-2024
Tcl-Version:	9.0
Tcl-Branch:	tip-690
Vote-Summary:   Accepted 6/0/0
Votes-For:      AK, FV, JN, MC, KW, SL
Votes-Against:  None
Votes-Present:  None

Abstract

TIP 688 introduced a new clock scan -validate 1 option, which can detect more errors in the string being parsed, in stead of trying to output a best-guess. This TIP proposes to make 1 the default. If you don't want that, use clock scan -validate 0.

Rationale

The current Tcl clock scan command accepts a wide range of strings as dates which are obviously not a valid date string and does a "best-guess" for this strings. This is not only true for the so called "free format scan" but even if the -format option is used.

Example:

    % clock scan 2024-30-40 -format %Y-%m-%d -gmt 1
    1783641600
    % clock format 1783641600 -format %Y-%m-%d -gmt 1
    2026-07-10

This behaviour is rarely useful while validating user input. And is almost never useful while parsing data formats which include dates. A common pattern to overcome this clock scan behaviour in practise if not using the "free form scan" is to string compare the original date string with the result after a round-trip:

    set date 2024-30-40
    if {$date ne [clock format [clock scan $date -format %Y-%m-%d -gmt 1] -format %Y-%m-%d -gmt 1]} {
        # Not a valid date
    }

Since TIP 688 is is possible to use just the -validate 1 flag instead. And this works even for the "free format scan".

Since "clock scan" is throwing an exception for some errors, but just gives an illogical answer for other situations, this TIP proposes to throw an exception for all such situations instead.

Example:

    $ tclsh9.0
    % clock scan "feb 30, 2024 12:00" -gmt 1
    unable to convert input string: invalid day

This behaviour change was left out of TIP 688 just to prevent that the discussion got sidetracked by this behaviour change from the main propose. The author of TIP 688 itself uses -validate 1 as default in his code.

In the supposed to be rare cases were the current "best-guess" clock scan behaviour is seen as feature this behaviour can be restored with a local -validate 0 flag:

Example:

    $ tclsh9.0
    % clock scan 2024-30-40 -format %Y-%m-%d -gmt 1 -validate 0
    1783641600

In Tcl 8.6, this command (without -validate 0) gives the same answer 1783641600, which corresponds to the 1th of March.

Specification

If the -validate option is not specified in the clock scan command, the value 1 will be assumed.

Note that the -validate option is located inside the (undocumented) ::tcl::unsupported::clock::configure command. It is likely that this command will be removed in a future Tcl version.

Compatibility

Very probably there is code out which banks on the current clock scan behaviour to work as expected (e.g. splitting a date like 2023-11-03 into integers(!), do arithmetic as add 6 month, concat to a date string and clock scan that). In that cases -validate 0 must be used.

But in much more cases this behaviour change would improve the quality of existing reasonable code. Since clock scan right now raises error on format error

Example:

    % clock scan 2023-10-ab -format %Y-%m-%d
    input string does not match supplied format

such code has error handling at that places. In this cases the detection of not valid date strings will just be better.

Implementation

Implementation is in TCL branch "tip-690".

Copyright

This document has been placed in the public domain.