With #31953 we moved the factories for components, directives and pipes into a new field called `ngFactoryDef`, however I decided not to do it for injectables, because they needed some extra logic. These changes set up the `ngFactoryDef` for injectables as well. For reference, the extra logic mentioned above is that for injectables we have two code paths: 1. For injectables that don't configure how they should be instantiated, we create a `factory` that proxies to `ngFactoryDef`: ``` // Source @Injectable() class Service {} // Output class Service { static ngInjectableDef = defineInjectable({ factory: () => Service.ngFactoryFn(), }); static ngFactoryFn: (t) => new (t || Service)(); } ``` 2. For injectables that do configure how they're created, we keep the `ngFactoryDef` and generate the factory based on the metadata: ``` // Source @Injectable({ useValue: DEFAULT_IMPL, }) class Service {} // Output export class Service { static ngInjectableDef = defineInjectable({ factory: () => DEFAULT_IMPL, }); static ngFactoryFn: (t) => new (t || Service)(); } ``` PR Close #32433
180 lines
14 KiB
TypeScript
180 lines
14 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {Inject, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
|
|
import {formatDate} from '../i18n/format_date';
|
|
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
|
|
|
|
// clang-format off
|
|
/**
|
|
* @ngModule CommonModule
|
|
* @description
|
|
*
|
|
* Formats a date value according to locale rules.
|
|
*
|
|
* Only the `en-US` locale data comes with Angular. To localize dates
|
|
* in another language, you must import the corresponding locale data.
|
|
* See the [I18n guide](guide/i18n#i18n-pipes) for more information.
|
|
*
|
|
* @see `formatDate()`
|
|
*
|
|
*
|
|
* @usageNotes
|
|
*
|
|
* The result of this pipe is not reevaluated when the input is mutated. To avoid the need to
|
|
* reformat the date on every change-detection cycle, treat the date as an immutable object
|
|
* and change the reference when the pipe needs to run again.
|
|
*
|
|
* ### Pre-defined format options
|
|
*
|
|
* Examples are given in `en-US` locale.
|
|
*
|
|
* - `'short'`: equivalent to `'M/d/yy, h:mm a'` (`6/15/15, 9:03 AM`).
|
|
* - `'medium'`: equivalent to `'MMM d, y, h:mm:ss a'` (`Jun 15, 2015, 9:03:01 AM`).
|
|
* - `'long'`: equivalent to `'MMMM d, y, h:mm:ss a z'` (`June 15, 2015 at 9:03:01 AM
|
|
* GMT+1`).
|
|
* - `'full'`: equivalent to `'EEEE, MMMM d, y, h:mm:ss a zzzz'` (`Monday, June 15, 2015 at
|
|
* 9:03:01 AM GMT+01:00`).
|
|
* - `'shortDate'`: equivalent to `'M/d/yy'` (`6/15/15`).
|
|
* - `'mediumDate'`: equivalent to `'MMM d, y'` (`Jun 15, 2015`).
|
|
* - `'longDate'`: equivalent to `'MMMM d, y'` (`June 15, 2015`).
|
|
* - `'fullDate'`: equivalent to `'EEEE, MMMM d, y'` (`Monday, June 15, 2015`).
|
|
* - `'shortTime'`: equivalent to `'h:mm a'` (`9:03 AM`).
|
|
* - `'mediumTime'`: equivalent to `'h:mm:ss a'` (`9:03:01 AM`).
|
|
* - `'longTime'`: equivalent to `'h:mm:ss a z'` (`9:03:01 AM GMT+1`).
|
|
* - `'fullTime'`: equivalent to `'h:mm:ss a zzzz'` (`9:03:01 AM GMT+01:00`).
|
|
*
|
|
* ### Custom format options
|
|
*
|
|
* You can construct a format string using symbols to specify the components
|
|
* of a date-time value, as described in the following table.
|
|
* Format details depend on the locale.
|
|
* Fields marked with (*) are only available in the extra data set for the given locale.
|
|
*
|
|
* | Field type | Format | Description | Example Value |
|
|
* |--------------------|-------------|---------------------------------------------------------------|------------------------------------------------------------|
|
|
* | Era | G, GG & GGG | Abbreviated | AD |
|
|
* | | GGGG | Wide | Anno Domini |
|
|
* | | GGGGG | Narrow | A |
|
|
* | Year | y | Numeric: minimum digits | 2, 20, 201, 2017, 20173 |
|
|
* | | yy | Numeric: 2 digits + zero padded | 02, 20, 01, 17, 73 |
|
|
* | | yyy | Numeric: 3 digits + zero padded | 002, 020, 201, 2017, 20173 |
|
|
* | | yyyy | Numeric: 4 digits or more + zero padded | 0002, 0020, 0201, 2017, 20173 |
|
|
* | Month | M | Numeric: 1 digit | 9, 12 |
|
|
* | | MM | Numeric: 2 digits + zero padded | 09, 12 |
|
|
* | | MMM | Abbreviated | Sep |
|
|
* | | MMMM | Wide | September |
|
|
* | | MMMMM | Narrow | S |
|
|
* | Month standalone | L | Numeric: 1 digit | 9, 12 |
|
|
* | | LL | Numeric: 2 digits + zero padded | 09, 12 |
|
|
* | | LLL | Abbreviated | Sep |
|
|
* | | LLLL | Wide | September |
|
|
* | | LLLLL | Narrow | S |
|
|
* | Week of year | w | Numeric: minimum digits | 1... 53 |
|
|
* | | ww | Numeric: 2 digits + zero padded | 01... 53 |
|
|
* | Week of month | W | Numeric: 1 digit | 1... 5 |
|
|
* | Day of month | d | Numeric: minimum digits | 1 |
|
|
* | | dd | Numeric: 2 digits + zero padded | 01 |
|
|
* | Week day | E, EE & EEE | Abbreviated | Tue |
|
|
* | | EEEE | Wide | Tuesday |
|
|
* | | EEEEE | Narrow | T |
|
|
* | | EEEEEE | Short | Tu |
|
|
* | Period | a, aa & aaa | Abbreviated | am/pm or AM/PM |
|
|
* | | aaaa | Wide (fallback to `a` when missing) | ante meridiem/post meridiem |
|
|
* | | aaaaa | Narrow | a/p |
|
|
* | Period* | B, BB & BBB | Abbreviated | mid. |
|
|
* | | BBBB | Wide | am, pm, midnight, noon, morning, afternoon, evening, night |
|
|
* | | BBBBB | Narrow | md |
|
|
* | Period standalone* | b, bb & bbb | Abbreviated | mid. |
|
|
* | | bbbb | Wide | am, pm, midnight, noon, morning, afternoon, evening, night |
|
|
* | | bbbbb | Narrow | md |
|
|
* | Hour 1-12 | h | Numeric: minimum digits | 1, 12 |
|
|
* | | hh | Numeric: 2 digits + zero padded | 01, 12 |
|
|
* | Hour 0-23 | H | Numeric: minimum digits | 0, 23 |
|
|
* | | HH | Numeric: 2 digits + zero padded | 00, 23 |
|
|
* | Minute | m | Numeric: minimum digits | 8, 59 |
|
|
* | | mm | Numeric: 2 digits + zero padded | 08, 59 |
|
|
* | Second | s | Numeric: minimum digits | 0... 59 |
|
|
* | | ss | Numeric: 2 digits + zero padded | 00... 59 |
|
|
* | Fractional seconds | S | Numeric: 1 digit | 0... 9 |
|
|
* | | SS | Numeric: 2 digits + zero padded | 00... 99 |
|
|
* | | SSS | Numeric: 3 digits + zero padded (= milliseconds) | 000... 999 |
|
|
* | Zone | z, zz & zzz | Short specific non location format (fallback to O) | GMT-8 |
|
|
* | | 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 |
|
|
*
|
|
* Note that timezone correction is not applied to an ISO string that has no time component, such as "2016-09-19"
|
|
*
|
|
* ### Format examples
|
|
*
|
|
* These examples transform a date into various formats,
|
|
* assuming that `dateObj` is a JavaScript `Date` object for
|
|
* year: 2015, month: 6, day: 15, hour: 21, minute: 43, second: 11,
|
|
* given in the local time for the `en-US` locale.
|
|
*
|
|
* ```
|
|
* {{ dateObj | date }} // output is 'Jun 15, 2015'
|
|
* {{ dateObj | date:'medium' }} // output is 'Jun 15, 2015, 9:43:11 PM'
|
|
* {{ dateObj | date:'shortTime' }} // output is '9:43 PM'
|
|
* {{ dateObj | date:'mm:ss' }} // output is '43:11'
|
|
* ```
|
|
*
|
|
* ### Usage example
|
|
*
|
|
* The following component uses a date pipe to display the current date in different formats.
|
|
*
|
|
* ```
|
|
* @Component({
|
|
* selector: 'date-pipe',
|
|
* template: `<div>
|
|
* <p>Today is {{today | date}}</p>
|
|
* <p>Or if you prefer, {{today | date:'fullDate'}}</p>
|
|
* <p>The time is {{today | date:'h:mm a z'}}</p>
|
|
* </div>`
|
|
* })
|
|
* // Get the current date and time as a date-time value.
|
|
* export class DatePipeComponent {
|
|
* today: number = Date.now();
|
|
* }
|
|
* ```
|
|
*
|
|
* @publicApi
|
|
*/
|
|
// clang-format on
|
|
@Pipe({name: 'date', pure: true})
|
|
export class DatePipe implements PipeTransform {
|
|
constructor(@Inject(LOCALE_ID) private locale: string) {}
|
|
|
|
/**
|
|
* @param value The date expression: a `Date` object, a number
|
|
* (milliseconds since UTC epoch), or an ISO string (https://www.w3.org/TR/NOTE-datetime).
|
|
* @param format The date/time components to include, using predefined options or a
|
|
* custom format string.
|
|
* @param timezone A timezone offset (such as `'+0430'`), or a standard
|
|
* UTC/GMT or continental US timezone abbreviation.
|
|
* When not supplied, uses the end-user's local system timezone.
|
|
* @param locale A locale code for the locale format rules to use.
|
|
* When not supplied, uses the value of `LOCALE_ID`, which is `en-US` by default.
|
|
* See [Setting your app locale](guide/i18n#setting-up-the-locale-of-your-app).
|
|
* @returns A date string in the desired format.
|
|
*/
|
|
transform(value: any, format = 'mediumDate', timezone?: string, locale?: string): string|null {
|
|
if (value == null || value === '' || value !== value) return null;
|
|
|
|
try {
|
|
return formatDate(value, format, locale || this.locale, timezone);
|
|
} catch (error) {
|
|
throw invalidPipeArgumentError(DatePipe, error.message);
|
|
}
|
|
}
|
|
}
|