From Delphi 2010 on, the RTL's TryStrToDateTime skips every character that is not a digit after the date. If no digit follows, it returns the date alone; if one does, it reads the time from there. Delphi 2009 and earlier rejected such strings. This is an RTL bug, but the dzlib functions that parse a date and time inherit it.
Measured with Delphi 12 (and the same with 2007 for comparison):
| Call | Delphi 12 | Delphi 2007 |
|---|---|---|
TryIso2DateTime('2026-10-14abc') |
True, 2026-10-14 | False |
TryIso2DateTime('2026-10-14 abc') |
True, 2026-10-14 | False |
TryIso2DateTime('2026-10-14X13:45') |
True, 2026-10-14 13:45 | False |
Tryddmmyyyyhhmmss2DateTime('14.10.2026abc') |
True, 2026-10-14 | False |
TryStr2DateTime('14/10/2026abc') |
True, 2026-10-14 | False |
TryStr2DateTime('2026-10-14abc') |
True, 2026-10-14 | False |
The date-only and time-only functions are not affected: TryIso2Date, Tryddmmyyyy2Date, TryStr2Date and TryIso2Time return False for these strings on both versions. Iso2DateTime, Str2DateTime and TryVar2DateTime delegate to the affected functions, so they accept the strings too.
The RTL behaves the same up to Delphi 13; measured on 2009 (rejects), 2010, XE, XE2, XE8, 10, 10.2, 10.4, 11, 12 and 13 (accept).
Fix: after parsing, check that nothing but blanks is left of the string, independently of what the RTL does. (The T between date and time in ISO 8601, [features:#35], is already handled by dzlib itself since r2441.)
reported to Embarcadero as SS-6154
Fixed in revision #2467.
TryIso2DateTime, Tryddmmyyyyhhmmss2DateTime and TryStr2DateTime no longer call the RTL's TryStrToDateTime. They split the string at a blank into a date and a time and leave the parts to TryStrToDate and TryStrToTime, which both check that nothing but blanks is left.
This also fixes a second case that is not in the list above: TryStrToDateTime never checks that the time reaches the end of the string. So
'2026-10-14 13:45 abc'and'2026-10-14 13:45:30 13'were accepted on every version measured (7, 2007, 12), and'2026-10-14 13:45abc'on Delphi 7 and 2007.With the German and UK formats, the fraction of a second may now follow a point or a comma whatever the locale's decimal separator is. On older versions (measured on 7 and 2007) the RTL reads it only after that separator, so
'14.10.2026 13:45:00.123'lost its milliseconds on a machine with a comma and would have been rejected by the stricter check. New tests in DateUtils.