77 */
88
99import { Inject , LOCALE_ID , Pipe , PipeTransform } from '@angular/core' ;
10-
1110import { NumberWrapper } from '../facade/lang' ;
12-
1311import { DateFormatter } from './intl' ;
1412import { InvalidPipeArgumentError } from './invalid_pipe_argument_error' ;
1513
16-
14+ const ISO8601_DATE_REGEX =
15+ / ^ ( \d { 4 } ) - ? ( \d \d ) - ? ( \d \d ) (?: T ( \d \d ) (?: : ? ( \d \d ) (?: : ? ( \d \d ) (?: \. ( \d + ) ) ? ) ? ) ? ( Z | ( [ + - ] ) ( \d \d ) : ? ( \d \d ) ) ? ) ? $ / ;
16+ // 1 2 3 4 5 6 7 8 9 10 11
1717
1818/**
1919 * @ngModule CommonModule
@@ -130,7 +130,12 @@ export class DatePipe implements PipeTransform {
130130 }
131131
132132 if ( ! isDate ( date ) ) {
133- throw new InvalidPipeArgumentError ( DatePipe , value ) ;
133+ let match : RegExpMatchArray ;
134+ if ( ( typeof value === 'string' ) && ( match = value . match ( ISO8601_DATE_REGEX ) ) ) {
135+ date = isoStringToDate ( match ) ;
136+ } else {
137+ throw new InvalidPipeArgumentError ( DatePipe , value ) ;
138+ }
134139 }
135140
136141 return DateFormatter . format ( date , this . _locale , DatePipe . _ALIASES [ pattern ] || pattern ) ;
@@ -144,3 +149,27 @@ function isBlank(obj: any): boolean {
144149function isDate ( obj : any ) : obj is Date {
145150 return obj instanceof Date && ! isNaN ( obj . valueOf ( ) ) ;
146151}
152+
153+ function isoStringToDate ( match : RegExpMatchArray ) : Date {
154+ const date = new Date ( 0 ) ;
155+ let tzHour = 0 ;
156+ let tzMin = 0 ;
157+ const dateSetter = match [ 8 ] ? date . setUTCFullYear : date . setFullYear ;
158+ const timeSetter = match [ 8 ] ? date . setUTCHours : date . setHours ;
159+
160+ if ( match [ 9 ] ) {
161+ tzHour = toInt ( match [ 9 ] + match [ 10 ] ) ;
162+ tzMin = toInt ( match [ 9 ] + match [ 11 ] ) ;
163+ }
164+ dateSetter . call ( date , toInt ( match [ 1 ] ) , toInt ( match [ 2 ] ) - 1 , toInt ( match [ 3 ] ) ) ;
165+ const h = toInt ( match [ 4 ] || '0' ) - tzHour ;
166+ const m = toInt ( match [ 5 ] || '0' ) - tzMin ;
167+ const s = toInt ( match [ 6 ] || '0' ) ;
168+ const ms = Math . round ( parseFloat ( '0.' + ( match [ 7 ] || 0 ) ) * 1000 ) ;
169+ timeSetter . call ( date , h , m , s , ms ) ;
170+ return date ;
171+ }
172+
173+ function toInt ( str : string ) : number {
174+ return parseInt ( str , 10 ) ;
175+ }
0 commit comments