Item13708: Foswiki::Time::parseTime()'s ISO date regex should be tightened, leads to weird table sorting
Priority: Enhancement
Current State: Confirmed
Released In: 2.2.0
Target Release: minor
Foswiki::Time::parseTime() will identify any string containing a capital T and a four-digit number as ISO date. This leads to a peculiar sort order for a table column that contains regular text (which sometimes includes a number).
The current code at
lib/Foswiki/Time.pm
lines 161ff:
# ISO date 2001-12-31T23:59:59+01:00
# Sven is going to presume that _all_ ISO dated must have a 'T' in them.
if (
( $date =~ m/T/ )
&& ( $date =~
m/(\d\d\d\d)(?:-(\d\d)(?:-(\d\d))?)?(?:T(\d\d)(?::(\d\d)(?::(\d\d(?:\.\d+)?))?)?)?(Z|[-+]\d\d(?::\d\d)?)?/
)
)
{
my ( $Y, $M, $D, $h, $m, $s, $tz ) =
( $1, $2 || 1, $3 || 1, $4 || 0, $5 || 0, $6 || 0, $7 || '' );
Suggested improvements:
- Make sure the 'T' is actually part of the parsed date expression
- Since the 'T' is already mandatory, month and day should also be mandatory, as should a time component - hour or even hour and minute? (ISO 8601 only uses a 'T' for concatenation of a complete date with any length time expression)
- Use of dashes and colons is optional in the ISO standard
- Anchor the pattern to the beginning of the string - who wants to sort by dates in the middle of the string? BTW some other regexes in parseTime() are anchored to the start and end of $date, but others (e.g. Foswiki date) are not.
My suggestion:
- m/(\d\d\d\d)(?:-(\d\d)(?:-(\d\d))?)?(?:T(\d\d)(?::(\d\d)(?::(\d\d(?:\.\d+)?))?)?)?(Z|[-+]\d\d(?::\d\d)?)?/
+ m/^(\d\d\d\d)-?(\d\d)-?(\d\d)T(\d\d)(?::?(\d\d)(?::?(\d\d(?:\.\d+)?))?)?(Z|[-+]\d\d(?::\d\d)?)?/
As this is very old code pre-dating the git history, and might be in use from many places, I'd prefer some positive feedback. I have checked that the TimeTests unit tests still pass, without modification.
--
FlorianSchlichting - 16 Sep 2015