Summary
Contact birthday and anniversary fields in Turba can display ICU format pattern text (for example MMM d, yyyy or medium) instead of a formatted date. With German locale and a typical Horde date preference such as %x, the UI may also show a two-digit year (for example 08.08.84) when locale-specific strftime conversion maps to ICU short.
Stored values in the database are usually correct (for example 1984-08-08). The failure is in the web UI display path.
Environment
- Horde 6 / Turba 5
- PHP with the
intl extension available
- Turba contact attributes
birthday and anniversary use form type monthdayyear
- Turba
Application::_normalizeDateAttributes() supplies:
format_in such as yyyy-MM-dd
format_out derived from the user Horde date_format preference (converted from strftime to ICU)
- an
IcuFormatter instance
- locale from the user language preference
Steps to reproduce
- Set Horde language to German and a typical date display preference (for example
%x).
- Open a Turba contact with a birthday stored as
1984-08-08.
- View the contact in read-only form rendering (
Turba_View_Contact / inactive form display).
Expected behavior
The birthday is shown as a human-readable date in the user locale and chosen date format (for example 08.08.1984 in German).
Actual behavior
The UI may show:
- the literal ICU pattern text (
MMM d, yyyy),
- the literal shortcut name (
medium),
- or a locale
short date with a two-digit year (08.08.84),
instead of a properly formatted date.
Technical analysis
Turba prepares ICU-aware field parameters
In Turba_Application::_normalizeDateAttributes(), Turba rewrites monthdayyear and datetime field params to ICU-oriented format_in / format_out, attaches an IcuFormatter, and passes locale (and a timezone placeholder) into the form layer.
For locale-specific strftime values such as %x, conversion can yield an ICU shortcut such as short or medium, not a strftime pattern.
V3 MonthdayyearVariable does not match the legacy formatter path
When the modern V3 form class exists, Horde Form uses Horde\Form\V3\MonthdayyearVariable.
In the affected upstream code, that class only handled the first five init() parameters (start_year, end_year, picker, format_in, format_out) and rendered dates with:
return $date->strftime($this->_format_out);
Horde_Date::strftime() does not interpret ICU patterns or ICU shortcuts. For example:
strftime('MMM d, yyyy') returns the literal string MMM d, yyyy
strftime('medium') returns the literal string medium
Turba can therefore pass correct ICU display settings while the V3 field still uses the legacy strftime path.
Legacy PSR-0 type already supports formatter mode
The older Horde_Form_Type_monthdayyear in lib/Horde/Form/Type.php already accepts formatter, locale, and timezone in init() and uses formatter mode in formatDate() when a FormatterInterface is provided:
if ($this->_isFormatterMode()) {
$locale = $this->_resolveLocale();
return $date->format($this->_format_out, $this->_formatter, $locale);
}
return $date->strftime($this->_format_out);
The V3 port is incomplete relative to the legacy implementation.
Related: V3 DatetimeVariable
Horde\Form\V3\DatetimeVariable composes an internal MonthdayyearVariable, but its init() only forwards the first five date parameters to the nested object. It does not forward formatter, locale, or timezone.
The legacy Horde_Form_Type_datetime does forward those arguments to the nested month/day/year type.
Turba default contact attributes do not use datetime, but any application that passes ICU formatter settings into datetime fields through the same parameter layout would hit the same gap on the V3 path.
Types that do not appear affected by the same bug
monthyear: no ICU format_out display path
time / hourminutesecond: separate time handling
date (DateVariable): different display mechanism
Suggested fix
-
Bring Horde\Form\V3\MonthdayyearVariable in line with Horde_Form_Type_monthdayyear:
- accept formatter, locale, and timezone in
init()
- use formatter mode in
formatDate() and storage formatting when a formatter is present
- keep strftime behavior as fallback when no formatter is configured
-
Update Horde\Form\V3\DatetimeVariable to forward formatter, locale, and timezone to its nested MonthdayyearVariable, matching the legacy datetime type.
-
Review locale-specific strftime conversion for %x and similar values so display does not fall back to English-looking ICU defaults or short two-digit years when a full locale date is intended.
Summary
Contact birthday and anniversary fields in Turba can display ICU format pattern text (for example
MMM d, yyyyormedium) instead of a formatted date. With German locale and a typical Horde date preference such as%x, the UI may also show a two-digit year (for example08.08.84) when locale-specific strftime conversion maps to ICUshort.Stored values in the database are usually correct (for example
1984-08-08). The failure is in the web UI display path.Environment
intlextension availablebirthdayandanniversaryuse form typemonthdayyearApplication::_normalizeDateAttributes()supplies:format_insuch asyyyy-MM-ddformat_outderived from the user Hordedate_formatpreference (converted from strftime to ICU)IcuFormatterinstanceSteps to reproduce
%x).1984-08-08.Turba_View_Contact/ inactive form display).Expected behavior
The birthday is shown as a human-readable date in the user locale and chosen date format (for example
08.08.1984in German).Actual behavior
The UI may show:
MMM d, yyyy),medium),shortdate with a two-digit year (08.08.84),instead of a properly formatted date.
Technical analysis
Turba prepares ICU-aware field parameters
In
Turba_Application::_normalizeDateAttributes(), Turba rewritesmonthdayyearanddatetimefield params to ICU-orientedformat_in/format_out, attaches anIcuFormatter, and passes locale (and a timezone placeholder) into the form layer.For locale-specific strftime values such as
%x, conversion can yield an ICU shortcut such asshortormedium, not a strftime pattern.V3
MonthdayyearVariabledoes not match the legacy formatter pathWhen the modern V3 form class exists, Horde Form uses
Horde\Form\V3\MonthdayyearVariable.In the affected upstream code, that class only handled the first five
init()parameters (start_year,end_year,picker,format_in,format_out) and rendered dates with:Horde_Date::strftime()does not interpret ICU patterns or ICU shortcuts. For example:strftime('MMM d, yyyy')returns the literal stringMMM d, yyyystrftime('medium')returns the literal stringmediumTurba can therefore pass correct ICU display settings while the V3 field still uses the legacy strftime path.
Legacy PSR-0 type already supports formatter mode
The older
Horde_Form_Type_monthdayyearinlib/Horde/Form/Type.phpalready accepts formatter, locale, and timezone ininit()and uses formatter mode informatDate()when aFormatterInterfaceis provided:The V3 port is incomplete relative to the legacy implementation.
Related: V3
DatetimeVariableHorde\Form\V3\DatetimeVariablecomposes an internalMonthdayyearVariable, but itsinit()only forwards the first five date parameters to the nested object. It does not forward formatter, locale, or timezone.The legacy
Horde_Form_Type_datetimedoes forward those arguments to the nested month/day/year type.Turba default contact attributes do not use
datetime, but any application that passes ICU formatter settings intodatetimefields through the same parameter layout would hit the same gap on the V3 path.Types that do not appear affected by the same bug
monthyear: no ICUformat_outdisplay pathtime/hourminutesecond: separate time handlingdate(DateVariable): different display mechanismSuggested fix
Bring
Horde\Form\V3\MonthdayyearVariablein line withHorde_Form_Type_monthdayyear:init()formatDate()and storage formatting when a formatter is presentUpdate
Horde\Form\V3\DatetimeVariableto forward formatter, locale, and timezone to its nestedMonthdayyearVariable, matching the legacy datetime type.Review locale-specific strftime conversion for
%xand similar values so display does not fall back to English-looking ICU defaults orshorttwo-digit years when a full locale date is intended.