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:
parent
6f017a4d60
commit
c56ecab515
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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':
|
||||||
|
|
|
@ -54,65 +54,70 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
|
||||||
* Format details depend on the locale.
|
* Format details depend on the locale.
|
||||||
* Fields marked with (*) are only available in the extra data set for the given locale.
|
* Fields marked with (*) are only available in the extra data set for the given locale.
|
||||||
*
|
*
|
||||||
* | Field type | Format | Description | Example Value |
|
* | Field type | Format | Description | Example Value |
|
||||||
* |--------------------|-------------|---------------------------------------------------------------|------------------------------------------------------------|
|
* |-------------------- |-------------|---------------------------------------------------------------|------------------------------------------------------------|
|
||||||
* | Era | G, GG & GGG | Abbreviated | AD |
|
* | Era | G, GG & GGG | Abbreviated | AD |
|
||||||
* | | GGGG | Wide | Anno Domini |
|
* | | GGGG | Wide | Anno Domini |
|
||||||
* | | GGGGG | Narrow | A |
|
* | | GGGGG | Narrow | A |
|
||||||
* | Year | y | Numeric: minimum digits | 2, 20, 201, 2017, 20173 |
|
* | Year | y | Numeric: minimum digits | 2, 20, 201, 2017, 20173 |
|
||||||
* | | yy | Numeric: 2 digits + zero padded | 02, 20, 01, 17, 73 |
|
* | | yy | Numeric: 2 digits + zero padded | 02, 20, 01, 17, 73 |
|
||||||
* | | yyy | Numeric: 3 digits + zero padded | 002, 020, 201, 2017, 20173 |
|
* | | yyy | Numeric: 3 digits + zero padded | 002, 020, 201, 2017, 20173 |
|
||||||
* | | yyyy | Numeric: 4 digits or more + zero padded | 0002, 0020, 0201, 2017, 20173 |
|
* | | yyyy | Numeric: 4 digits or more + zero padded | 0002, 0020, 0201, 2017, 20173 |
|
||||||
* | Week-numbering year| Y | Numeric: minimum digits | 2, 20, 201, 2017, 20173 |
|
* | Week-numbering year | Y | Numeric: minimum digits | 2, 20, 201, 2017, 20173 |
|
||||||
* | | YY | Numeric: 2 digits + zero padded | 02, 20, 01, 17, 73 |
|
* | | YY | Numeric: 2 digits + zero padded | 02, 20, 01, 17, 73 |
|
||||||
* | | YYY | Numeric: 3 digits + zero padded | 002, 020, 201, 2017, 20173 |
|
* | | YYY | Numeric: 3 digits + zero padded | 002, 020, 201, 2017, 20173 |
|
||||||
* | | YYYY | Numeric: 4 digits or more + zero padded | 0002, 0020, 0201, 2017, 20173 |
|
* | | YYYY | Numeric: 4 digits or more + zero padded | 0002, 0020, 0201, 2017, 20173 |
|
||||||
* | Month | M | Numeric: 1 digit | 9, 12 |
|
* | Month | M | Numeric: 1 digit | 9, 12 |
|
||||||
* | | MM | Numeric: 2 digits + zero padded | 09, 12 |
|
* | | MM | Numeric: 2 digits + zero padded | 09, 12 |
|
||||||
* | | MMM | Abbreviated | Sep |
|
* | | MMM | Abbreviated | Sep |
|
||||||
* | | MMMM | Wide | September |
|
* | | MMMM | Wide | September |
|
||||||
* | | MMMMM | Narrow | S |
|
* | | MMMMM | Narrow | S |
|
||||||
* | Month standalone | L | Numeric: 1 digit | 9, 12 |
|
* | Month standalone | L | Numeric: 1 digit | 9, 12 |
|
||||||
* | | LL | Numeric: 2 digits + zero padded | 09, 12 |
|
* | | LL | Numeric: 2 digits + zero padded | 09, 12 |
|
||||||
* | | LLL | Abbreviated | Sep |
|
* | | LLL | Abbreviated | Sep |
|
||||||
* | | LLLL | Wide | September |
|
* | | LLLL | Wide | September |
|
||||||
* | | LLLLL | Narrow | S |
|
* | | LLLLL | Narrow | S |
|
||||||
* | Week of year | w | Numeric: minimum digits | 1... 53 |
|
* | Week of year | w | Numeric: minimum digits | 1... 53 |
|
||||||
* | | ww | Numeric: 2 digits + zero padded | 01... 53 |
|
* | | ww | Numeric: 2 digits + zero padded | 01... 53 |
|
||||||
* | Week of month | W | Numeric: 1 digit | 1... 5 |
|
* | Week of month | W | Numeric: 1 digit | 1... 5 |
|
||||||
* | Day of month | d | Numeric: minimum digits | 1 |
|
* | Day of month | d | Numeric: minimum digits | 1 |
|
||||||
* | | dd | Numeric: 2 digits + zero padded | 01 |
|
* | | dd | Numeric: 2 digits + zero padded | 01 |
|
||||||
* | Week day | E, EE & EEE | Abbreviated | Tue |
|
* | Week day | E, EE & EEE | Abbreviated | Tue |
|
||||||
* | | EEEE | Wide | Tuesday |
|
* | | EEEE | Wide | Tuesday |
|
||||||
* | | EEEEE | Narrow | T |
|
* | | EEEEE | Narrow | T |
|
||||||
* | | EEEEEE | Short | Tu |
|
* | | EEEEEE | Short | Tu |
|
||||||
* | Period | a, aa & aaa | Abbreviated | am/pm or AM/PM |
|
* | Week day standalone | c, cc | Numeric: 1 digit | 2 |
|
||||||
* | | aaaa | Wide (fallback to `a` when missing) | ante meridiem/post meridiem |
|
* | | ccc | Abbreviated | Tue |
|
||||||
* | | aaaaa | Narrow | a/p |
|
* | | cccc | Wide | Tuesday |
|
||||||
* | Period* | B, BB & BBB | Abbreviated | mid. |
|
* | | ccccc | Narrow | T |
|
||||||
* | | BBBB | Wide | am, pm, midnight, noon, morning, afternoon, evening, night |
|
* | | cccccc | Short | Tu |
|
||||||
* | | BBBBB | Narrow | md |
|
* | Period | a, aa & aaa | Abbreviated | am/pm or AM/PM |
|
||||||
* | Period standalone* | b, bb & bbb | Abbreviated | mid. |
|
* | | aaaa | Wide (fallback to `a` when missing) | ante meridiem/post meridiem |
|
||||||
* | | bbbb | Wide | am, pm, midnight, noon, morning, afternoon, evening, night |
|
* | | aaaaa | Narrow | a/p |
|
||||||
* | | bbbbb | Narrow | md |
|
* | Period* | B, BB & BBB | Abbreviated | mid. |
|
||||||
* | Hour 1-12 | h | Numeric: minimum digits | 1, 12 |
|
* | | BBBB | Wide | am, pm, midnight, noon, morning, afternoon, evening, night |
|
||||||
* | | hh | Numeric: 2 digits + zero padded | 01, 12 |
|
* | | BBBBB | Narrow | md |
|
||||||
* | Hour 0-23 | H | Numeric: minimum digits | 0, 23 |
|
* | Period standalone* | b, bb & bbb | Abbreviated | mid. |
|
||||||
* | | HH | Numeric: 2 digits + zero padded | 00, 23 |
|
* | | bbbb | Wide | am, pm, midnight, noon, morning, afternoon, evening, night |
|
||||||
* | Minute | m | Numeric: minimum digits | 8, 59 |
|
* | | bbbbb | Narrow | md |
|
||||||
* | | mm | Numeric: 2 digits + zero padded | 08, 59 |
|
* | Hour 1-12 | h | Numeric: minimum digits | 1, 12 |
|
||||||
* | Second | s | Numeric: minimum digits | 0... 59 |
|
* | | hh | Numeric: 2 digits + zero padded | 01, 12 |
|
||||||
* | | ss | Numeric: 2 digits + zero padded | 00... 59 |
|
* | Hour 0-23 | H | Numeric: minimum digits | 0, 23 |
|
||||||
* | Fractional seconds | S | Numeric: 1 digit | 0... 9 |
|
* | | HH | Numeric: 2 digits + zero padded | 00, 23 |
|
||||||
* | | SS | Numeric: 2 digits + zero padded | 00... 99 |
|
* | Minute | m | Numeric: minimum digits | 8, 59 |
|
||||||
* | | SSS | Numeric: 3 digits + zero padded (= milliseconds) | 000... 999 |
|
* | | mm | Numeric: 2 digits + zero padded | 08, 59 |
|
||||||
* | Zone | z, zz & zzz | Short specific non location format (fallback to O) | GMT-8 |
|
* | Second | s | Numeric: minimum digits | 0... 59 |
|
||||||
* | | zzzz | Long specific non location format (fallback to OOOO) | GMT-08:00 |
|
* | | ss | Numeric: 2 digits + zero padded | 00... 59 |
|
||||||
* | | Z, ZZ & ZZZ | ISO8601 basic format | -0800 |
|
* | Fractional seconds | S | Numeric: 1 digit | 0... 9 |
|
||||||
* | | ZZZZ | Long localized GMT format | GMT-8:00 |
|
* | | SS | Numeric: 2 digits + zero padded | 00... 99 |
|
||||||
* | | ZZZZZ | ISO8601 extended format + Z indicator for offset 0 (= XXXXX) | -08:00 |
|
* | | SSS | Numeric: 3 digits + zero padded (= milliseconds) | 000... 999 |
|
||||||
* | | O, OO & OOO | Short localized GMT format | GMT-8 |
|
* | Zone | z, zz & zzz | Short specific non location format (fallback to O) | GMT-8 |
|
||||||
* | | OOOO | Long localized GMT format | GMT-08:00 |
|
* | | zzzz | Long specific non location format (fallback to OOOO) | GMT-08:00 |
|
||||||
|
* | | Z, ZZ & ZZZ | ISO8601 basic format | -0800 |
|
||||||
|
* | | ZZZZ | Long localized GMT format | GMT-8:00 |
|
||||||
|
* | | ZZZZZ | ISO8601 extended format + Z indicator for offset 0 (= XXXXX) | -08:00 |
|
||||||
|
* | | O, OO & OOO | Short localized GMT format | GMT-8 |
|
||||||
|
* | | OOOO | Long localized GMT format | GMT-08:00 |
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* ### Format examples
|
* ### Format examples
|
||||||
|
|
|
@ -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');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue