feat(common): support ICU standard "stand alone day of week" with DatePipe (#40766)

This commit adds support for Finnish full date formatting,
as well as `c/cc/ccc/cccc/ccccc/cccccc` date formats in the `DatePipe`.

Fixes #26922

PR Close #40766
This commit is contained in:
kirjs 2021-02-09 14:53:48 -05:00 committed by Joey Perrott
parent 6f017a4d60
commit c56ecab515
4 changed files with 106 additions and 62 deletions

View File

@ -30,7 +30,7 @@
"master": { "master": {
"uncompressed": { "uncompressed": {
"runtime-es2015": 1485, "runtime-es2015": 1485,
"main-es2015": 136703, "main-es2015": 137236,
"polyfills-es2015": 37641 "polyfills-es2015": 37641
} }
} }

View File

@ -13,7 +13,7 @@ export const ISO8601_DATE_REGEX =
// 1 2 3 4 5 6 7 8 9 10 11 // 1 2 3 4 5 6 7 8 9 10 11
const NAMED_FORMATS: {[localeId: string]: {[format: string]: string}} = {}; const NAMED_FORMATS: {[localeId: string]: {[format: string]: string}} = {};
const DATE_FORMATS_SPLIT = const DATE_FORMATS_SPLIT =
/((?:[^GyYMLwWdEabBhHmsSzZO']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/; /((?:[^BEGHLMOSWYZabcdhmswyz']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|c{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/;
enum ZoneWidth { enum ZoneWidth {
Short, Short,
@ -445,7 +445,7 @@ const DATE_FORMATS: {[format: string]: DateFormatter} = {};
// Based on CLDR formats: // Based on CLDR formats:
// See complete list: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table // See complete list: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
// See also explanations: http://cldr.unicode.org/translation/date-time // See also explanations: http://cldr.unicode.org/translation/date-time
// TODO(ocombe): support all missing cldr formats: Y, U, Q, D, F, e, c, j, J, C, A, v, V, X, x // TODO(ocombe): support all missing cldr formats: U, Q, D, F, e, j, J, C, A, v, V, X, x
function getDateFormatter(format: string): DateFormatter|null { function getDateFormatter(format: string): DateFormatter|null {
if (DATE_FORMATS[format]) { if (DATE_FORMATS[format]) {
return DATE_FORMATS[format]; return DATE_FORMATS[format];
@ -557,6 +557,26 @@ function getDateFormatter(format: string): DateFormatter|null {
formatter = dateGetter(DateType.Date, 2); formatter = dateGetter(DateType.Date, 2);
break; break;
// Day of the Week StandAlone (1, 1, Mon, Monday, M, Mo)
case 'c':
case 'cc':
formatter = dateGetter(DateType.Day, 1);
break;
case 'ccc':
formatter =
dateStrGetter(TranslationType.Days, TranslationWidth.Abbreviated, FormStyle.Standalone);
break;
case 'cccc':
formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Wide, FormStyle.Standalone);
break;
case 'ccccc':
formatter =
dateStrGetter(TranslationType.Days, TranslationWidth.Narrow, FormStyle.Standalone);
break;
case 'cccccc':
formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Short, FormStyle.Standalone);
break;
// Day of the Week // Day of the Week
case 'E': case 'E':
case 'EE': case 'EE':

View File

@ -86,6 +86,11 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
* | | EEEE | Wide | Tuesday | * | | EEEE | Wide | Tuesday |
* | | EEEEE | Narrow | T | * | | EEEEE | Narrow | T |
* | | EEEEEE | Short | Tu | * | | EEEEEE | Short | Tu |
* | Week day standalone | c, cc | Numeric: 1 digit | 2 |
* | | ccc | Abbreviated | Tue |
* | | cccc | Wide | Tuesday |
* | | ccccc | Narrow | T |
* | | cccccc | Short | Tu |
* | Period | a, aa & aaa | Abbreviated | am/pm or AM/PM | * | Period | a, aa & aaa | Abbreviated | am/pm or AM/PM |
* | | aaaa | Wide (fallback to `a` when missing) | ante meridiem/post meridiem | * | | aaaa | Wide (fallback to `a` when missing) | ante meridiem/post meridiem |
* | | aaaaa | Narrow | a/p | * | | aaaaa | Narrow | a/p |

View File

@ -9,6 +9,7 @@ import localeAr from '@angular/common/locales/ar';
import localeDe from '@angular/common/locales/de'; import localeDe from '@angular/common/locales/de';
import localeEn from '@angular/common/locales/en'; import localeEn from '@angular/common/locales/en';
import localeEnExtra from '@angular/common/locales/extra/en'; import localeEnExtra from '@angular/common/locales/extra/en';
import localeFi from '@angular/common/locales/fi';
import localeHu from '@angular/common/locales/hu'; import localeHu from '@angular/common/locales/hu';
import localeSr from '@angular/common/locales/sr'; import localeSr from '@angular/common/locales/sr';
import localeTh from '@angular/common/locales/th'; import localeTh from '@angular/common/locales/th';
@ -78,6 +79,7 @@ describe('Format date', () => {
ɵregisterLocaleData(localeSr); ɵregisterLocaleData(localeSr);
ɵregisterLocaleData(localeTh); ɵregisterLocaleData(localeTh);
ɵregisterLocaleData(localeAr); ɵregisterLocaleData(localeAr);
ɵregisterLocaleData(localeFi);
}); });
afterAll(() => ɵunregisterLocaleData()); afterAll(() => ɵunregisterLocaleData());
@ -116,6 +118,12 @@ describe('Format date', () => {
W: '3', W: '3',
d: '15', d: '15',
dd: '15', dd: '15',
c: '1',
cc: '1',
ccc: 'Mon',
cccc: 'Monday',
ccccc: 'M',
cccccc: 'Mo',
E: 'Mon', E: 'Mon',
EE: 'Mon', EE: 'Mon',
EEE: 'Mon', EEE: 'Mon',
@ -178,6 +186,12 @@ describe('Format date', () => {
W: '1', W: '1',
d: '1', d: '1',
dd: '01', dd: '01',
c: '4',
cc: '4',
ccc: 'Thu',
cccc: 'Thursday',
ccccc: 'T',
cccccc: 'Th',
E: 'Thu', E: 'Thu',
EE: 'Thu', EE: 'Thu',
EEE: 'Thu', EEE: 'Thu',
@ -427,5 +441,10 @@ describe('Format date', () => {
expect(formatDate('0001-01-11', 'YYYY', ɵDEFAULT_LOCALE_ID)).toEqual('0001'); expect(formatDate('0001-01-11', 'YYYY', ɵDEFAULT_LOCALE_ID)).toEqual('0001');
expect(formatDate('0000-01-11', 'YYYY', ɵDEFAULT_LOCALE_ID)).toEqual('0000'); expect(formatDate('0000-01-11', 'YYYY', ɵDEFAULT_LOCALE_ID)).toEqual('0000');
}); });
// https://github.com/angular/angular/issues/26922
it('should support fullDate in finnish, which uses standalone week day', () => {
expect(formatDate(date, 'fullDate', 'fi')).toMatch('maanantai 15. kesäkuuta 2015');
});
}); });
}); });