← board

StrToTime raises the wrong class, and rejects milliseconds

1. The exception class — the half that matters

input before FPC
'nope' Exception EConvertError
'' Exception EConvertError
'25:00:00' Exception EConvertError
'13:99:00' Exception EConvertError
'13:05x' Exception EConvertError

on E: EConvertError do is the handler an FPC or Delphi caller writes around a parse. A bare Exception is not that class, so the handler does not fire and the exception escapes to whatever catches Exception — or to the top. The failure mode is a program that looks correctly defensive and is not.

Every other arm of this family (StrToInt, StrToInt64, StrToFloat, StrToQWord) already raised EConvertError; this one was the odd arm out — the same "one arm of a double case was fixed and the sibling forgotten" shape as the StrToFloat ticket above.

FPC's message is "%s" is not a valid time — note it differs in wording from the integer arms' "%s" is an invalid integer. Matched exactly, since callers match on message text.

2. Milliseconds — and the rule is NOT what it looks like

StrToTime('13:05:09.250') raised here and parses in FPC. The obvious implementation is a decimal fraction of a second. Measured, that is wrong:

input decimal-fraction reading FPC (measured)
'13:05:09.250' 250 ms 250 ms
'13:05:09.25' 250 ms 25 ms
'13:05:09.2' 200 ms 2 ms
'13:05:09.1234' 123 ms (truncate) raises
'13:05.5' 500 ms raises

So FPC's fraction is a millisecond field, read as a plain integer: at most three digits, a fourth is an error rather than a truncation, and it is only allowed after a full h:m:s. '.25' means 25 ms.

This ticket exists partly as a record of that: the padding implementation was written, and only the differential probe caught it — three of the five rows above would have shipped wrong, silently, as times off by a factor of ten or a hundred.

Fix

Gate

Two probes identical to FPC — the basic surface (10 rows: h/h:m/h:m:s, ms, malformed, empty, out-of-range hour and minute, surrounding spaces, trailing junk) and the fraction edges (13 rows: 1/2/3/4 fraction digits, a bare separator, a fraction after h:m, .5 alone, 00:00:00.001, 23:59:59.999, and the message text on every raising row). make lib-test green.

Still missing from this family — filed separately

StrToDate, StrToDateTime and the TryStrTo* date variants do not exist in this RTL at all; only StrToTime does. See [[feature-lib-sysutils-strtodate-and-strtodatetime]].

Log