Here's some date-parsing stupidity from CFML that James Buckingham put onto my radar.
In a change from usual, here's the output (and the code will follow):
English (UK)
Raw | parsed | locale-aware parsed |
---|---|---|
30/2/13 | {ts '1930-02-13 00:00:00'} | - |
30 February 13 | {ts '1930-02-13 00:00:00'} | - |
Raw | parsed | locale-aware parsed |
---|---|---|
28/2/13 | {ts '2028-02-13 00:00:00'} | {ts '2013-02-28 00:00:00'} |
28 February 13 | {ts '2013-02-28 00:00:00'} | {ts '2013-02-28 00:00:00'} |
English (US)
Raw | parsed | locale-aware parsed |
---|---|---|
30/2/13 | {ts '1930-02-13 00:00:00'} | {ts '1930-02-13 00:00:00'} |
30 February 13 | {ts '1930-02-13 00:00:00'} | {ts '1930-02-13 00:00:00'} |
Raw | parsed | locale-aware parsed |
---|---|---|
28/2/13 | {ts '2028-02-13 00:00:00'} | {ts '2028-02-13 00:00:00'} |
28 February 13 | {ts '2013-02-28 00:00:00'} | {ts '2013-02-28 00:00:00'} |
This is just bloody stupid (and I'm sure I've touched on it before), but there is not situation in which a string formatted as "xx/xx/xx" should be interpreted as a date "yy/mm/dd". No-one writes dates as "yy/mm/dd". They might write it "yy-mm-dd", but the only time slashes are used is when the date is in "dd/mm/yy" (if you're a normal person) or "mm/dd/yy" (if your a USAn person). But that formatting never means "year first". So CF should not accept "30/2/13" as a date, because there is no 30th of Feburary, nor is there a month "Vigintioctober". So "30/2/13" is not a date, should fail validation checks, and error if one attempts to parse it as a date.
Ditto... CF can't go "well '30 February 13' means '1930 February 13th", but '28 February 13' means '28 February 2013'". No. Pick a format. it's either "dd mmmm yy" or "yy mmmm dd". Don't chop and change. You stupid language. And I severely doubt anyone on the planet would see a string of format "xx mmmm yy" as "yy mmmm dd" anyhow. I'm less sure of this than I am that "yy/mm/dd" doesn't exist, but moderately sure.
What was the person who wrote this validation / parsing code thinking: "I know, I'll accept any old shit and if there's even the slightest chance I can interpret it as a date, I will"? Because that's how it seems.
And that is stupid.
Here's the code:
for (locale in ["english (uk)", "english (us)"]){
setLocale(locale);
writeOutput("<h3>#getLocale()#</h3>");
datesTable(["30/2/13","30 February 13"]);
writeOutput("<br>");
datesTable(["28/2/13","28 February 13"]);
writeOutput("<hr>");
}
public void function datesTable(dates){
writeOutput('<table border="1"><thead><tr><th>Raw</th><th>parsed</th><th>locale-aware parsed</th></tr></thead><tbody>');
for (date in dates) {
writeOutput("<tr><td>#date#</td>");
if (isValid("date", date)){
writeOutput("<td>#parseDateTime(date)#</td>");
}else{
writeOutput("<td>-</td>");
}
if (isValidDateForCurrentLocale(date)){
writeOutput("<td>#parseDateTimeForCurrentLocale(date)#</td>");
}else{
writeOutput("<td>-</td>");
}
writeOutput("</tr>");
}
writeOutput('</tbody></table>');
}
public boolean function isValidDateForCurrentLocale(required string date){
var locale = getLocale();
var validator = "eurodate";
if (locale == "english (us)"){
validator = "date";
}
return isValid(validator, date);
}
public date function parseDateTimeForCurrentLocale(required string date){
var locale = getLocale();
if (locale == "english (us)"){
return parseDateTime(date);
}else{
return lsParseDateTime(date);
}
}
I had to write those two little locale-aware functions at the bottom as I can't see a way of getting CFML to go "parse the string according to my current locale". I have to manually use either US-locale-specific functions, or non-US-locale-specific functions.
BTW, Adobe: it's not a eurodate, it's just "a date". It's the States that have got the weirdo formatting, not Europe (and, indeed, everywhere else in the English-speaking world). Canada is not in Europe. Australia is not in Europe. New Zealand... not in Europe. you get my drift. Gotta love hard-coded jingoism.
--
Adam