diff --git a/modules/@angular/common/src/pipes/date_pipe.ts b/modules/@angular/common/src/pipes/date_pipe.ts index 7bd3a5b07b..b51aae585c 100644 --- a/modules/@angular/common/src/pipes/date_pipe.ts +++ b/modules/@angular/common/src/pipes/date_pipe.ts @@ -1,7 +1,7 @@ import {Pipe, PipeTransform} from '@angular/core'; -import {isDate, isNumber, isString, DateWrapper, isBlank,} from '../facade/lang'; -import {DateFormatter} from '../facade/intl'; import {StringMapWrapper} from '../facade/collection'; +import {DateFormatter} from '../facade/intl'; +import {DateWrapper, NumberWrapper, isBlank, isDate, isString} from '../facade/lang'; import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception'; // TODO: move to a global configurable location along with other i18n components. @@ -98,8 +98,8 @@ export class DatePipe implements PipeTransform { throw new InvalidPipeArgumentException(DatePipe, value); } - if (isNumber(value)) { - value = DateWrapper.fromMillis(value); + if (NumberWrapper.isNumeric(value)) { + value = DateWrapper.fromMillis(NumberWrapper.parseInt(value, 10)); } else if (isString(value)) { value = DateWrapper.fromISOString(value); } @@ -110,7 +110,7 @@ export class DatePipe implements PipeTransform { } private supports(obj: any): boolean { - if (isDate(obj) || isNumber(obj)) { + if (isDate(obj) || NumberWrapper.isNumeric(obj)) { return true; } if (isString(obj) && isDate(DateWrapper.fromISOString(obj))) { diff --git a/modules/@angular/common/test/pipes/date_pipe_spec.ts b/modules/@angular/common/test/pipes/date_pipe_spec.ts index 8ae821255c..e0c2a704ad 100644 --- a/modules/@angular/common/test/pipes/date_pipe_spec.ts +++ b/modules/@angular/common/test/pipes/date_pipe_spec.ts @@ -25,6 +25,9 @@ export function main() { describe('supports', () => { it('should support date', () => { expect(() => pipe.transform(date)).not.toThrow(); }); it('should support int', () => { expect(() => pipe.transform(123456789)).not.toThrow(); }); + it('should support numeric strings', + () => { expect(() => pipe.transform('123456789')).not.toThrow(); }); + it('should support ISO string', () => { expect(() => pipe.transform('2015-06-15T21:43:11Z')).not.toThrow(); }); diff --git a/modules/@angular/facade/src/lang.dart b/modules/@angular/facade/src/lang.dart index e6ad0d798d..451b0d39f6 100644 --- a/modules/@angular/facade/src/lang.dart +++ b/modules/@angular/facade/src/lang.dart @@ -189,6 +189,13 @@ class NumberWrapper { static double get NaN => double.NAN; + static bool isNumeric(value) { + if(value == null) { + return false; + } + return double.parse(value, (e) => null) != null; + } + static bool isNaN(num value) => value.isNaN; static bool isInteger(value) => value is int; diff --git a/modules/@angular/facade/src/lang.ts b/modules/@angular/facade/src/lang.ts index 2c00c6fa61..31a24f4702 100644 --- a/modules/@angular/facade/src/lang.ts +++ b/modules/@angular/facade/src/lang.ts @@ -320,6 +320,8 @@ export class NumberWrapper { static get NaN(): number { return NaN; } + static isNumeric(value: any): boolean { return !isNaN(value - parseFloat(value)); } + static isNaN(value: any): boolean { return isNaN(value); } static isInteger(value: any): boolean { return Number.isInteger(value); } diff --git a/modules/@angular/facade/test/lang_spec.ts b/modules/@angular/facade/test/lang_spec.ts index 6b8d6c42a4..902f2f5e23 100644 --- a/modules/@angular/facade/test/lang_spec.ts +++ b/modules/@angular/facade/test/lang_spec.ts @@ -1,6 +1,5 @@ import {beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing'; - -import {RegExpMatcherWrapper, RegExpWrapper, StringWrapper, hasConstructor, isPresent, resolveEnumToken} from '../src/lang'; +import {NumberWrapper, RegExpMatcherWrapper, RegExpWrapper, StringWrapper, hasConstructor, isPresent, resolveEnumToken} from '../src/lang'; enum UsefulEnum { MyToken, @@ -51,6 +50,28 @@ export function main() { }); }); + describe('Number', () => { + describe('isNumeric', () => { + it('should return true when passing correct numeric string', + () => { expect(NumberWrapper.isNumeric('2')).toBe(true); }); + + it('should return true when passing correct double string', + () => { expect(NumberWrapper.isNumeric('1.123')).toBe(true); }); + + it('should return true when passing correct negative string', + () => { expect(NumberWrapper.isNumeric('-2')).toBe(true); }); + + it('should return true when passing correct scientific notation string', + () => { expect(NumberWrapper.isNumeric('1e5')).toBe(true); }); + + it('should return false when passing incorrect numeric', + () => { expect(NumberWrapper.isNumeric('a')).toBe(false); }); + + it('should return false when passing parseable but non numeric', + () => { expect(NumberWrapper.isNumeric('2a')).toBe(false); }); + }); + }); + describe('String', () => { var s: any /** TODO #9100 */;