mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Expose date symbols and patterns for en_US in framework (#67900)
* Expose date symbols and patterns for en_US in framework
This commit is contained in:
parent
8aee75f645
commit
244f5ab598
@ -75,6 +75,7 @@ Future<void> main(List<String> rawArgs) async {
|
|||||||
final Directory datePatternsDirectory = Directory(path.join(pathToIntl, 'src', 'data', 'dates', 'patterns'));
|
final Directory datePatternsDirectory = Directory(path.join(pathToIntl, 'src', 'data', 'dates', 'patterns'));
|
||||||
final Map<String, File> patternFiles = _listIntlData(datePatternsDirectory);
|
final Map<String, File> patternFiles = _listIntlData(datePatternsDirectory);
|
||||||
final StringBuffer buffer = StringBuffer();
|
final StringBuffer buffer = StringBuffer();
|
||||||
|
final Set<String> supportedLocales = _supportedLocales();
|
||||||
|
|
||||||
buffer.writeln(
|
buffer.writeln(
|
||||||
'''
|
'''
|
||||||
@ -94,7 +95,7 @@ Future<void> main(List<String> rawArgs) async {
|
|||||||
buffer.writeln('const Map<String, dynamic> dateSymbols = <String, dynamic> {');
|
buffer.writeln('const Map<String, dynamic> dateSymbols = <String, dynamic> {');
|
||||||
symbolFiles.forEach((String locale, File data) {
|
symbolFiles.forEach((String locale, File data) {
|
||||||
currentLocale = locale;
|
currentLocale = locale;
|
||||||
if (_supportedLocales().contains(locale))
|
if (supportedLocales.contains(locale))
|
||||||
buffer.writeln(_jsonToMapEntry(locale, json.decode(data.readAsStringSync())));
|
buffer.writeln(_jsonToMapEntry(locale, json.decode(data.readAsStringSync())));
|
||||||
});
|
});
|
||||||
currentLocale = null;
|
currentLocale = null;
|
||||||
@ -107,7 +108,7 @@ Future<void> main(List<String> rawArgs) async {
|
|||||||
/// supported by flutter_localizations.''');
|
/// supported by flutter_localizations.''');
|
||||||
buffer.writeln('const Map<String, Map<String, String>> datePatterns = <String, Map<String, String>> {');
|
buffer.writeln('const Map<String, Map<String, String>> datePatterns = <String, Map<String, String>> {');
|
||||||
patternFiles.forEach((String locale, File data) {
|
patternFiles.forEach((String locale, File data) {
|
||||||
if (_supportedLocales().contains(locale)) {
|
if (supportedLocales.contains(locale)) {
|
||||||
final Map<String, dynamic> patterns = json.decode(data.readAsStringSync()) as Map<String, dynamic>;
|
final Map<String, dynamic> patterns = json.decode(data.readAsStringSync()) as Map<String, dynamic>;
|
||||||
buffer.writeln("'$locale': <String, String>{");
|
buffer.writeln("'$locale': <String, String>{");
|
||||||
patterns.forEach((String key, dynamic value) {
|
patterns.forEach((String key, dynamic value) {
|
||||||
@ -164,13 +165,21 @@ String _jsonToMap(dynamic json) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Set<String> _supportedLocales() {
|
Set<String> _supportedLocales() {
|
||||||
final Set<String> supportedLocales = <String>{};
|
// Assumes that en_US is a supported locale by default. Without this, usage
|
||||||
|
// of the intl package APIs before Flutter populates its set of supported i18n
|
||||||
|
// date patterns and symbols may cause problems.
|
||||||
|
//
|
||||||
|
// For more context, see https://github.com/flutter/flutter/issues/67644.
|
||||||
|
final Set<String> supportedLocales = <String>{
|
||||||
|
'en_US',
|
||||||
|
};
|
||||||
final RegExp filenameRE = RegExp(r'(?:material|cupertino)_(\w+)\.arb$');
|
final RegExp filenameRE = RegExp(r'(?:material|cupertino)_(\w+)\.arb$');
|
||||||
final Directory supportedLocalesDirectory = Directory(path.join('packages', 'flutter_localizations', 'lib', 'src', 'l10n'));
|
final Directory supportedLocalesDirectory = Directory(path.join('packages', 'flutter_localizations', 'lib', 'src', 'l10n'));
|
||||||
for (final FileSystemEntity entity in supportedLocalesDirectory.listSync()) {
|
for (final FileSystemEntity entity in supportedLocalesDirectory.listSync()) {
|
||||||
final String filePath = entity.path;
|
final String filePath = entity.path;
|
||||||
if (FileSystemEntity.isFileSync(filePath) && filenameRE.hasMatch(filePath))
|
if (FileSystemEntity.isFileSync(filePath) && filenameRE.hasMatch(filePath)) {
|
||||||
supportedLocales.add(filenameRE.firstMatch(filePath)[1]);
|
supportedLocales.add(filenameRE.firstMatch(filePath)[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return supportedLocales;
|
return supportedLocales;
|
||||||
|
@ -4001,6 +4001,196 @@ const Map<String, dynamic> dateSymbols = <String, dynamic>{
|
|||||||
'{1}, {0}',
|
'{1}, {0}',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
'en_US': <String, dynamic>{
|
||||||
|
'NAME': 'en_US',
|
||||||
|
'ERAS': <dynamic>[
|
||||||
|
'BC',
|
||||||
|
'AD',
|
||||||
|
],
|
||||||
|
'ERANAMES': <dynamic>[
|
||||||
|
'Before Christ',
|
||||||
|
'Anno Domini',
|
||||||
|
],
|
||||||
|
'NARROWMONTHS': <dynamic>[
|
||||||
|
'J',
|
||||||
|
'F',
|
||||||
|
'M',
|
||||||
|
'A',
|
||||||
|
'M',
|
||||||
|
'J',
|
||||||
|
'J',
|
||||||
|
'A',
|
||||||
|
'S',
|
||||||
|
'O',
|
||||||
|
'N',
|
||||||
|
'D',
|
||||||
|
],
|
||||||
|
'STANDALONENARROWMONTHS': <dynamic>[
|
||||||
|
'J',
|
||||||
|
'F',
|
||||||
|
'M',
|
||||||
|
'A',
|
||||||
|
'M',
|
||||||
|
'J',
|
||||||
|
'J',
|
||||||
|
'A',
|
||||||
|
'S',
|
||||||
|
'O',
|
||||||
|
'N',
|
||||||
|
'D',
|
||||||
|
],
|
||||||
|
'MONTHS': <dynamic>[
|
||||||
|
'January',
|
||||||
|
'February',
|
||||||
|
'March',
|
||||||
|
'April',
|
||||||
|
'May',
|
||||||
|
'June',
|
||||||
|
'July',
|
||||||
|
'August',
|
||||||
|
'September',
|
||||||
|
'October',
|
||||||
|
'November',
|
||||||
|
'December',
|
||||||
|
],
|
||||||
|
'STANDALONEMONTHS': <dynamic>[
|
||||||
|
'January',
|
||||||
|
'February',
|
||||||
|
'March',
|
||||||
|
'April',
|
||||||
|
'May',
|
||||||
|
'June',
|
||||||
|
'July',
|
||||||
|
'August',
|
||||||
|
'September',
|
||||||
|
'October',
|
||||||
|
'November',
|
||||||
|
'December',
|
||||||
|
],
|
||||||
|
'SHORTMONTHS': <dynamic>[
|
||||||
|
'Jan',
|
||||||
|
'Feb',
|
||||||
|
'Mar',
|
||||||
|
'Apr',
|
||||||
|
'May',
|
||||||
|
'Jun',
|
||||||
|
'Jul',
|
||||||
|
'Aug',
|
||||||
|
'Sep',
|
||||||
|
'Oct',
|
||||||
|
'Nov',
|
||||||
|
'Dec',
|
||||||
|
],
|
||||||
|
'STANDALONESHORTMONTHS': <dynamic>[
|
||||||
|
'Jan',
|
||||||
|
'Feb',
|
||||||
|
'Mar',
|
||||||
|
'Apr',
|
||||||
|
'May',
|
||||||
|
'Jun',
|
||||||
|
'Jul',
|
||||||
|
'Aug',
|
||||||
|
'Sep',
|
||||||
|
'Oct',
|
||||||
|
'Nov',
|
||||||
|
'Dec',
|
||||||
|
],
|
||||||
|
'WEEKDAYS': <dynamic>[
|
||||||
|
'Sunday',
|
||||||
|
'Monday',
|
||||||
|
'Tuesday',
|
||||||
|
'Wednesday',
|
||||||
|
'Thursday',
|
||||||
|
'Friday',
|
||||||
|
'Saturday',
|
||||||
|
],
|
||||||
|
'STANDALONEWEEKDAYS': <dynamic>[
|
||||||
|
'Sunday',
|
||||||
|
'Monday',
|
||||||
|
'Tuesday',
|
||||||
|
'Wednesday',
|
||||||
|
'Thursday',
|
||||||
|
'Friday',
|
||||||
|
'Saturday',
|
||||||
|
],
|
||||||
|
'SHORTWEEKDAYS': <dynamic>[
|
||||||
|
'Sun',
|
||||||
|
'Mon',
|
||||||
|
'Tue',
|
||||||
|
'Wed',
|
||||||
|
'Thu',
|
||||||
|
'Fri',
|
||||||
|
'Sat',
|
||||||
|
],
|
||||||
|
'STANDALONESHORTWEEKDAYS': <dynamic>[
|
||||||
|
'Sun',
|
||||||
|
'Mon',
|
||||||
|
'Tue',
|
||||||
|
'Wed',
|
||||||
|
'Thu',
|
||||||
|
'Fri',
|
||||||
|
'Sat',
|
||||||
|
],
|
||||||
|
'NARROWWEEKDAYS': <dynamic>[
|
||||||
|
'S',
|
||||||
|
'M',
|
||||||
|
'T',
|
||||||
|
'W',
|
||||||
|
'T',
|
||||||
|
'F',
|
||||||
|
'S',
|
||||||
|
],
|
||||||
|
'STANDALONENARROWWEEKDAYS': <dynamic>[
|
||||||
|
'S',
|
||||||
|
'M',
|
||||||
|
'T',
|
||||||
|
'W',
|
||||||
|
'T',
|
||||||
|
'F',
|
||||||
|
'S',
|
||||||
|
],
|
||||||
|
'SHORTQUARTERS': <dynamic>[
|
||||||
|
'Q1',
|
||||||
|
'Q2',
|
||||||
|
'Q3',
|
||||||
|
'Q4',
|
||||||
|
],
|
||||||
|
'QUARTERS': <dynamic>[
|
||||||
|
'1st quarter',
|
||||||
|
'2nd quarter',
|
||||||
|
'3rd quarter',
|
||||||
|
'4th quarter',
|
||||||
|
],
|
||||||
|
'AMPMS': <dynamic>[
|
||||||
|
'AM',
|
||||||
|
'PM',
|
||||||
|
],
|
||||||
|
'DATEFORMATS': <dynamic>[
|
||||||
|
'EEEE, MMMM d, y',
|
||||||
|
'MMMM d, y',
|
||||||
|
'MMM d, y',
|
||||||
|
'M/d/yy',
|
||||||
|
],
|
||||||
|
'TIMEFORMATS': <dynamic>[
|
||||||
|
'h:mm:ss a zzzz',
|
||||||
|
'h:mm:ss a z',
|
||||||
|
'h:mm:ss a',
|
||||||
|
'h:mm a',
|
||||||
|
],
|
||||||
|
'AVAILABLEFORMATS': null,
|
||||||
|
'FIRSTDAYOFWEEK': 6,
|
||||||
|
'WEEKENDRANGE': <dynamic>[
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
],
|
||||||
|
'FIRSTWEEKCUTOFFDAY': 5,
|
||||||
|
'DATETIMEFORMATS': <dynamic>[
|
||||||
|
'{1} \'at\' {0}',
|
||||||
|
'{1} \'at\' {0}',
|
||||||
|
'{1}, {0}',
|
||||||
|
'{1}, {0}',
|
||||||
|
],
|
||||||
|
},
|
||||||
'en_ZA': <String, dynamic>{
|
'en_ZA': <String, dynamic>{
|
||||||
'NAME': 'en_ZA',
|
'NAME': 'en_ZA',
|
||||||
'ERAS': <dynamic>[
|
'ERAS': <dynamic>[
|
||||||
@ -18658,6 +18848,52 @@ const Map<String, Map<String, String>> datePatterns =
|
|||||||
'zzzz': 'zzzz',
|
'zzzz': 'zzzz',
|
||||||
'ZZZZ': 'ZZZZ',
|
'ZZZZ': 'ZZZZ',
|
||||||
},
|
},
|
||||||
|
'en_US': <String, String>{
|
||||||
|
'd': 'd',
|
||||||
|
'E': 'ccc',
|
||||||
|
'EEEE': 'cccc',
|
||||||
|
'LLL': 'LLL',
|
||||||
|
'LLLL': 'LLLL',
|
||||||
|
'M': 'L',
|
||||||
|
'Md': 'M/d',
|
||||||
|
'MEd': 'EEE, M/d',
|
||||||
|
'MMM': 'LLL',
|
||||||
|
'MMMd': 'MMM d',
|
||||||
|
'MMMEd': 'EEE, MMM d',
|
||||||
|
'MMMM': 'LLLL',
|
||||||
|
'MMMMd': 'MMMM d',
|
||||||
|
'MMMMEEEEd': 'EEEE, MMMM d',
|
||||||
|
'QQQ': 'QQQ',
|
||||||
|
'QQQQ': 'QQQQ',
|
||||||
|
'y': 'y',
|
||||||
|
'yM': 'M/y',
|
||||||
|
'yMd': 'M/d/y',
|
||||||
|
'yMEd': 'EEE, M/d/y',
|
||||||
|
'yMMM': 'MMM y',
|
||||||
|
'yMMMd': 'MMM d, y',
|
||||||
|
'yMMMEd': 'EEE, MMM d, y',
|
||||||
|
'yMMMM': 'MMMM y',
|
||||||
|
'yMMMMd': 'MMMM d, y',
|
||||||
|
'yMMMMEEEEd': 'EEEE, MMMM d, y',
|
||||||
|
'yQQQ': 'QQQ y',
|
||||||
|
'yQQQQ': 'QQQQ y',
|
||||||
|
'H': 'HH',
|
||||||
|
'Hm': 'HH:mm',
|
||||||
|
'Hms': 'HH:mm:ss',
|
||||||
|
'j': 'h a',
|
||||||
|
'jm': 'h:mm a',
|
||||||
|
'jms': 'h:mm:ss a',
|
||||||
|
'jmv': 'h:mm a v',
|
||||||
|
'jmz': 'h:mm a z',
|
||||||
|
'jz': 'h a z',
|
||||||
|
'm': 'm',
|
||||||
|
'ms': 'mm:ss',
|
||||||
|
's': 's',
|
||||||
|
'v': 'v',
|
||||||
|
'z': 'z',
|
||||||
|
'zzzz': 'zzzz',
|
||||||
|
'ZZZZ': 'ZZZZ',
|
||||||
|
},
|
||||||
'en_ZA': <String, String>{
|
'en_ZA': <String, String>{
|
||||||
'd': 'd',
|
'd': 'd',
|
||||||
'E': 'ccc',
|
'E': 'ccc',
|
||||||
|
@ -9,17 +9,18 @@ import '../l10n/generated_date_localizations.dart' as date_localizations;
|
|||||||
/// Tracks if date i18n data has been loaded.
|
/// Tracks if date i18n data has been loaded.
|
||||||
bool _dateIntlDataInitialized = false;
|
bool _dateIntlDataInitialized = false;
|
||||||
|
|
||||||
/// Loads i18n data for dates if it hasn't be loaded yet.
|
/// Loads i18n data for dates if it hasn't been loaded yet.
|
||||||
///
|
///
|
||||||
/// Only the first invocation of this function has the effect of loading the
|
/// Only the first invocation of this function loads the data. Subsequent
|
||||||
/// data. Subsequent invocations have no effect.
|
/// invocations have no effect.
|
||||||
void loadDateIntlDataIfNotLoaded() {
|
void loadDateIntlDataIfNotLoaded() {
|
||||||
if (!_dateIntlDataInitialized) {
|
if (!_dateIntlDataInitialized) {
|
||||||
// TODO(garyq): Add support for scriptCodes. Do not strip scriptCode from string.
|
// TODO(garyq): Add support for scriptCodes. Do not strip scriptCode from string.
|
||||||
|
|
||||||
// Keep track of initialzed locales, or will fail on attempted double init.
|
// Keeps track of initialized locales. This can only happen if a locale
|
||||||
// This can only happen if a locale with a stripped scriptCode has already
|
// with a stripped scriptCode has already been initialzed. The set of
|
||||||
// been initialzed. This should be removed when scriptCode stripping is removed.
|
// initialized locales should be removed when scriptCode stripping is
|
||||||
|
// removed.
|
||||||
final Set<String> initializedLocales = <String>{};
|
final Set<String> initializedLocales = <String>{};
|
||||||
date_localizations.dateSymbols
|
date_localizations.dateSymbols
|
||||||
.cast<String, Map<String, dynamic>>()
|
.cast<String, Map<String, dynamic>>()
|
||||||
|
@ -7,6 +7,7 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group(GlobalMaterialLocalizations, () {
|
group(GlobalMaterialLocalizations, () {
|
||||||
@ -159,6 +160,28 @@ void main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Regression test for https://github.com/flutter/flutter/issues/67644.
|
||||||
|
testWidgets('en_US is initialized correctly by Flutter when DateFormat is used', (WidgetTester tester) async {
|
||||||
|
DateFormat dateFormat;
|
||||||
|
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
supportedLocales: const <Locale>[
|
||||||
|
Locale('en', 'US'),
|
||||||
|
],
|
||||||
|
locale: const Locale('en', 'US'),
|
||||||
|
localizationsDelegates: const <LocalizationsDelegate<dynamic>>[
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
],
|
||||||
|
home: Builder(builder: (BuildContext context) {
|
||||||
|
dateFormat = DateFormat('EEE, d MMM yyyy HH:mm:ss', 'en_US');
|
||||||
|
|
||||||
|
return Container();
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(dateFormat?.locale, 'en_US');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DateType { year, medium, full, monthYear }
|
enum DateType { year, medium, full, monthYear }
|
||||||
|
Loading…
Reference in New Issue
Block a user