Use correct locale for CupertinoDatePicker weekday (#151494)

#120052 introduces the `showDayOfWeek` flag to `CupertinoDatePicker` for mode `CupertinoDatePickerMode.date`, but the default `en` locale from `DefaultCupertinoLocalizations` is always used for the day of the week:

5103d75743/packages/flutter_localizations/lib/src/cupertino_localizations.dart (L116-L119)

This PR introduces a new `intl.DateFormat` `weekdayFormat` to replace the default with the abbreviated weekday for any supported locales.

| Before | After | 
| --- | --- |
|  <img width="379" alt="Screenshot 2024-07-09 at 5 08 43 PM" src="https://github.com/flutter/flutter/assets/77553258/d6899c6b-bd0a-4484-a6a8-3ef1512aeae1">  |  <img width="379" alt="Screenshot 2024-07-09 at 5 08 11 PM" src="https://github.com/flutter/flutter/assets/77553258/f320c634-80d1-4f3b-adfd-ed85a9dfc3f6"> |

Fixes #141875
This commit is contained in:
Victor Sanni 2024-07-10 17:10:17 -07:00 committed by GitHub
parent a1bd8434b5
commit ceeeb7d090
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 258 additions and 126 deletions

View File

@ -41,6 +41,7 @@ String generateCupertinoConstructor(LocaleInfo locale) {
super.localeName = '$localeName', super.localeName = '$localeName',
required super.fullYearFormat, required super.fullYearFormat,
required super.dayFormat, required super.dayFormat,
required super.weekdayFormat,
required super.mediumDateFormat, required super.mediumDateFormat,
required super.singleDigitHourFormat, required super.singleDigitHourFormat,
required super.singleDigitMinuteFormat, required super.singleDigitMinuteFormat,
@ -57,6 +58,7 @@ GlobalCupertinoLocalizations? getCupertinoTranslation(
Locale locale, Locale locale,
intl.DateFormat fullYearFormat, intl.DateFormat fullYearFormat,
intl.DateFormat dayFormat, intl.DateFormat dayFormat,
intl.DateFormat weekdayFormat,
intl.DateFormat mediumDateFormat, intl.DateFormat mediumDateFormat,
intl.DateFormat singleDigitHourFormat, intl.DateFormat singleDigitHourFormat,
intl.DateFormat singleDigitMinuteFormat, intl.DateFormat singleDigitMinuteFormat,
@ -66,7 +68,7 @@ GlobalCupertinoLocalizations? getCupertinoTranslation(
) {'''; ) {''';
const String cupertinoFactoryArguments = const String cupertinoFactoryArguments =
'fullYearFormat: fullYearFormat, dayFormat: dayFormat, mediumDateFormat: mediumDateFormat, singleDigitHourFormat: singleDigitHourFormat, singleDigitMinuteFormat: singleDigitMinuteFormat, doubleDigitMinuteFormat: doubleDigitMinuteFormat, singleDigitSecondFormat: singleDigitSecondFormat, decimalFormat: decimalFormat'; 'fullYearFormat: fullYearFormat, dayFormat: dayFormat, weekdayFormat: weekdayFormat, mediumDateFormat: mediumDateFormat, singleDigitHourFormat: singleDigitHourFormat, singleDigitMinuteFormat: singleDigitMinuteFormat, doubleDigitMinuteFormat: doubleDigitMinuteFormat, singleDigitSecondFormat: singleDigitSecondFormat, decimalFormat: decimalFormat';
const String cupertinoSupportedLanguagesConstant = 'kCupertinoSupportedLanguages'; const String cupertinoSupportedLanguagesConstant = 'kCupertinoSupportedLanguages';

View File

@ -343,7 +343,7 @@ class DefaultCupertinoLocalizations implements CupertinoLocalizations {
const DefaultCupertinoLocalizations(); const DefaultCupertinoLocalizations();
/// Short version of days of week. /// Short version of days of week.
static const List<String> shortWeekdays = <String>[ static const List<String> _shortWeekdays = <String>[
'Mon', 'Mon',
'Tue', 'Tue',
'Wed', 'Wed',
@ -397,7 +397,7 @@ class DefaultCupertinoLocalizations implements CupertinoLocalizations {
@override @override
String datePickerDayOfMonth(int dayIndex, [int? weekDay]) { String datePickerDayOfMonth(int dayIndex, [int? weekDay]) {
if (weekDay != null) { if (weekDay != null) {
return ' ${shortWeekdays[weekDay - DateTime.monday]} $dayIndex '; return ' ${_shortWeekdays[weekDay - DateTime.monday]} $dayIndex ';
} }
return dayIndex.toString(); return dayIndex.toString();
@ -422,7 +422,7 @@ class DefaultCupertinoLocalizations implements CupertinoLocalizations {
@override @override
String datePickerMediumDate(DateTime date) { String datePickerMediumDate(DateTime date) {
return '${shortWeekdays[date.weekday - DateTime.monday]} ' return '${_shortWeekdays[date.weekday - DateTime.monday]} '
'${_shortMonths[date.month - DateTime.january]} ' '${_shortMonths[date.month - DateTime.january]} '
'${date.day.toString().padRight(2)}'; '${date.day.toString().padRight(2)}';
} }

View File

@ -61,6 +61,7 @@ abstract class GlobalCupertinoLocalizations implements CupertinoLocalizations {
required String localeName, required String localeName,
required intl.DateFormat fullYearFormat, required intl.DateFormat fullYearFormat,
required intl.DateFormat dayFormat, required intl.DateFormat dayFormat,
required intl.DateFormat weekdayFormat,
required intl.DateFormat mediumDateFormat, required intl.DateFormat mediumDateFormat,
required intl.DateFormat singleDigitHourFormat, required intl.DateFormat singleDigitHourFormat,
required intl.DateFormat singleDigitMinuteFormat, required intl.DateFormat singleDigitMinuteFormat,
@ -70,6 +71,7 @@ abstract class GlobalCupertinoLocalizations implements CupertinoLocalizations {
}) : _localeName = localeName, }) : _localeName = localeName,
_fullYearFormat = fullYearFormat, _fullYearFormat = fullYearFormat,
_dayFormat = dayFormat, _dayFormat = dayFormat,
_weekdayFormat = weekdayFormat,
_mediumDateFormat = mediumDateFormat, _mediumDateFormat = mediumDateFormat,
_singleDigitHourFormat = singleDigitHourFormat, _singleDigitHourFormat = singleDigitHourFormat,
_singleDigitMinuteFormat = singleDigitMinuteFormat, _singleDigitMinuteFormat = singleDigitMinuteFormat,
@ -80,6 +82,7 @@ abstract class GlobalCupertinoLocalizations implements CupertinoLocalizations {
final String _localeName; final String _localeName;
final intl.DateFormat _fullYearFormat; final intl.DateFormat _fullYearFormat;
final intl.DateFormat _dayFormat; final intl.DateFormat _dayFormat;
final intl.DateFormat _weekdayFormat;
final intl.DateFormat _mediumDateFormat; final intl.DateFormat _mediumDateFormat;
final intl.DateFormat _singleDigitHourFormat; final intl.DateFormat _singleDigitHourFormat;
final intl.DateFormat _singleDigitMinuteFormat; final intl.DateFormat _singleDigitMinuteFormat;
@ -114,11 +117,10 @@ abstract class GlobalCupertinoLocalizations implements CupertinoLocalizations {
@override @override
String datePickerDayOfMonth(int dayIndex, [int? weekDay]) { String datePickerDayOfMonth(int dayIndex, [int? weekDay]) {
if (weekDay != null) { return weekDay != null
return ' ${DefaultCupertinoLocalizations.shortWeekdays[weekDay - DateTime.monday]} $dayIndex '; ? '${_weekdayFormat.format(DateTime.utc(1, 1, weekDay))} ${_dayFormat.format(DateTime.utc(1, 1, dayIndex))}'
} // Year and month doesn't matter since we just want to day formatted.
// Year and month doesn't matter since we just want to day formatted. : _dayFormat.format(DateTime.utc(0, 0, dayIndex));
return _dayFormat.format(DateTime.utc(0, 0, dayIndex));
} }
@override @override
@ -486,6 +488,7 @@ class _GlobalCupertinoLocalizationsDelegate extends LocalizationsDelegate<Cupert
late intl.DateFormat fullYearFormat; late intl.DateFormat fullYearFormat;
late intl.DateFormat dayFormat; late intl.DateFormat dayFormat;
late intl.DateFormat weekdayFormat;
late intl.DateFormat mediumDateFormat; late intl.DateFormat mediumDateFormat;
// We don't want any additional decoration here. The am/pm is handled in // We don't want any additional decoration here. The am/pm is handled in
// the date picker. We just want an hour number localized. // the date picker. We just want an hour number localized.
@ -498,6 +501,7 @@ class _GlobalCupertinoLocalizationsDelegate extends LocalizationsDelegate<Cupert
void loadFormats(String? locale) { void loadFormats(String? locale) {
fullYearFormat = intl.DateFormat.y(locale); fullYearFormat = intl.DateFormat.y(locale);
dayFormat = intl.DateFormat.d(locale); dayFormat = intl.DateFormat.d(locale);
weekdayFormat = intl.DateFormat.E(locale);
mediumDateFormat = intl.DateFormat.MMMEd(locale); mediumDateFormat = intl.DateFormat.MMMEd(locale);
// TODO(xster): fix when https://github.com/dart-lang/intl/issues/207 is resolved. // TODO(xster): fix when https://github.com/dart-lang/intl/issues/207 is resolved.
singleDigitHourFormat = intl.DateFormat('HH', locale); singleDigitHourFormat = intl.DateFormat('HH', locale);
@ -519,6 +523,7 @@ class _GlobalCupertinoLocalizationsDelegate extends LocalizationsDelegate<Cupert
locale, locale,
fullYearFormat, fullYearFormat,
dayFormat, dayFormat,
weekdayFormat,
mediumDateFormat, mediumDateFormat,
singleDigitHourFormat, singleDigitHourFormat,
singleDigitMinuteFormat, singleDigitMinuteFormat,

View File

@ -239,6 +239,15 @@ void main() {
expect(localizations, isA<CupertinoLocalizationZh>()); expect(localizations, isA<CupertinoLocalizationZh>());
expect(localizations.lookUpButtonLabel, '查询'); expect(localizations.lookUpButtonLabel, '查询');
}); });
testWidgets('localizations.datePickerDayOfMonth uses the current locale for weekdays', (WidgetTester tester) async {
const Locale locale = Locale('zh');
expect(GlobalCupertinoLocalizations.delegate.isSupported(locale), isTrue);
final CupertinoLocalizations localizations = await GlobalCupertinoLocalizations.delegate.load(locale);
expect(localizations, isA<CupertinoLocalizationZh>());
expect(localizations.datePickerDayOfMonth(1), '1日');
expect(localizations.datePickerDayOfMonth(1, 2), '周二 1日');
});
} }
class _FakeEditableText extends EditableText { class _FakeEditableText extends EditableText {