SMF icon indicating copy to clipboard operation
SMF copied to clipboard

Invalid date when posting calendar event with default french format

Open Shiwa opened this issue 3 years ago • 7 comments

Description

We enabled the calendar feature on our forum. It worked fine, until an "Invalid date" error appeared when posting an event past the 12th of the month… which is almost certainly a parsing error of french date format (dd/mm/YYYY instead of american mm/dd/YYYY).

Changing the forum default date format to "%d %B %Y, %H:%M:%S" fixed the problem, but now the calendar date picker displays dates as "24 Novembre 20…" (long french format that does not fit in the box). Also manually typing the date into the picker using french short format dd/mm/YYYY causes the "Invalid date" error. Users of our forum are all french and I expect them to input "invalid dates" frequently.

Expected behaviour :

  • picking the date using the date picker component should allow to send the form with a date format that can be parsed by the server
  • manually entering the date should be disallowed or mark the field as invalid if the typed value can’t be parsed
  • french users (and locales with similar date formats) should be able to input dates in a short, familiar format

Steps to reproduce

  1. Enable calendar on an smf forum with french translation
  2. Post an event with a date past the 12th of the month (25th of december 2022) OR type directly the date in usual french format (25/12/2022) => the date picker is not marked as invalid, the preview works, but submitting the event leads to an "Invalid date" error page

Environment (complete as necessary)

  • Version/Git revision: 2.1.2
  • Database Type: mysql
  • Database Version:
  • PHP Version: 7.3

Additional information/references

Don’t every brother support input type="date" nowadays?

Shiwa avatar Nov 24 '22 22:11 Shiwa

Changing the forum default date format to "%d %B %Y, %H:%M:%S" fixed the problem, but now the calendar date picker displays dates as "24 Novembre 20…" (long french format that does not fit in the box).

As you have already discovered, the accepted input format for dates is determined by the display format for dates.

If the full month name doesn't fit in the input field, try changing %B to %b in the date display format.

Sesquipedalian avatar Nov 24 '22 23:11 Sesquipedalian

Using %b is a marginal improvement: the user still faces an unusual date picker and can face unexpected behavior by typing the date directly.

As a quickfix I removed the id="event_time_input" of the form div in the Post and Calendar templates, replaced <input type="text"…/> with type="date" / type="time" and replaced the $context['event']['start_date_orig']) values with $context['event']['start_date']). This replaces the jquery date picker with the modern built-in one, which is properly localized and sends value in ISO format. The UX is as expected.

Shiwa avatar Nov 26 '22 22:11 Shiwa

That will work if the user's browser supports <input type="date">. But that isn't supported by all the browsers that SMF supports, so we can't rely on it. In a future version we will be able to, but not yet.

Sesquipedalian avatar Nov 27 '22 06:11 Sesquipedalian

Do we have a list of browsers somewhere? IE is not supported anymore afaik and the date type support is strong.

DiegoAndresCortes avatar Nov 27 '22 08:11 DiegoAndresCortes

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date#browser_compatibility -> ✔️

isaak654 avatar Nov 27 '22 12:11 isaak654

In the case of Russian, I replaced $context['event']['start_date_orig'] and $context['event']['end_date_orig'] with $context['event']['start_date'] and $context['event']['end_date'], respectively. I also changed the convertDateToEnglish function slightly, since we don't use "am" and "pm" in dates:

function convertDateToEnglish($date)
{
	global $txt, $context;

	if ($context['user']['language'] == 'english')
		return $date;

	$replacements = array_combine(array_map('strtolower', $txt['months_titles']), array(
		'January', 'February', 'March', 'April', 'May', 'June',
		'July', 'August', 'September', 'October', 'November', 'December'
	));
	$replacements += array_combine(array_map('strtolower', $txt['months_short']), array(
		'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
		'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
	));
	$replacements += array_combine(array_map('strtolower', $txt['days']), array(
		'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
	));
	$replacements += array_combine(array_map('strtolower', $txt['days_short']), array(
		'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'
	));
	// Find all possible variants of AM and PM for this language.
	if ($txt['time_am'] != ' ' && $txt['time_pm'] != ' ') {
		$replacements[strtolower($txt['time_am'])] = 'AM';
		$replacements[strtolower($txt['time_pm'])] = 'PM';
		if (($am = smf_strftime('%p', strtotime('01:00:00'))) !== 'p' && $am !== false)
		{
			$replacements[strtolower($am)] = 'AM';
			$replacements[strtolower(smf_strftime('%p', strtotime('23:00:00')))] = 'PM';
		}
		if (($am = smf_strftime('%P', strtotime('01:00:00'))) !== 'P' && $am !== false)
		{
			$replacements[strtolower($am)] = 'AM';
			$replacements[strtolower(smf_strftime('%P', strtotime('23:00:00')))] = 'PM';
		}
	}

	return strtr(strtolower($date), $replacements);
}

dragomano avatar Mar 10 '23 05:03 dragomano

#8796 fixes this

jdarwood007 avatar Aug 24 '25 16:08 jdarwood007