diff options
| author | Di Peng | 2011-07-14 12:02:01 -0700 | 
|---|---|---|
| committer | Igor Minar | 2011-07-20 17:06:56 -0700 | 
| commit | 3af1e7ca2ee8c2acd69e5bcbb3ffc1bf51239285 (patch) | |
| tree | e354ff465d7f29e419591dd12fb7c9f48bd8bb81 | |
| parent | 0fbaa2f12ab96328fe2e7b4b9f3ec0c8d7f30e37 (diff) | |
| download | angular.js-3af1e7ca2ee8c2acd69e5bcbb3ffc1bf51239285.tar.bz2 | |
feat(filter.date): add support for default datetime formats in en
- add support for full,long, medium, short datetime formats in en
Breaks MMMMM. now we don't support MMMMM anymore as old implementation differs
from Unicode Locale Data format we are following.
- removed support for fullDateTime and fullTime as it means too much
trouble with full timeZone names
- added docs for the new features
| -rw-r--r-- | CHANGELOG.md | 3 | ||||
| -rw-r--r-- | src/filters.js | 69 | ||||
| -rw-r--r-- | test/FiltersSpec.js | 78 | ||||
| -rw-r--r-- | test/angular-mocksSpec.js | 10 | 
4 files changed, 133 insertions, 27 deletions
| diff --git a/CHANGELOG.md b/CHANGELOG.md index 45428ad4..dd2dcc97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@  <a name="0.9.18"><a/>  # <angular/> 0.9.18 jiggling-armfat (in-progress) # - +### Breaking changes +- no longer support MMMMM in filter.date as we need to follow UNICODE LOCALE DATA formats. diff --git a/src/filters.js b/src/filters.js index 1dd6322b..8fac671d 100644 --- a/src/filters.js +++ b/src/filters.js @@ -184,6 +184,17 @@ function dateStrGetter(name, shortForm) {    };  } +function timeZoneGetter(numFormat) { +  return function(date) { +    var timeZone; +    if (numFormat || !(timeZone = GET_TIME_ZONE.exec(date.toString()))) { +      var offset = date.getTimezoneOffset(); +      return padNumber(offset / 60, 2) + padNumber(Math.abs(offset % 60), 2); +    } +    return timeZone[0]; +  }; +} +  var DAY = 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(',');  var MONTH = 'January,February,March,April,May,June,July,August,September,October,November,December'. @@ -192,7 +203,8 @@ var MONTH = 'January,February,March,April,May,June,July,August,September,October  var DATE_FORMATS = {    yyyy: dateGetter('FullYear', 4),      yy: dateGetter('FullYear', 2, 0, true), - MMMMM: dateStrGetter('Month'), +     y: dateGetter('FullYear', 1), +  MMMM: dateStrGetter('Month'),     MMM: dateStrGetter('Month', true),      MM: dateGetter('Month', 2, 1),       M: dateGetter('Month', 1, 1), @@ -209,14 +221,26 @@ var DATE_FORMATS = {    EEEE: dateStrGetter('Day'),     EEE: dateStrGetter('Day', true),       a: function(date){return date.getHours() < 12 ? 'am' : 'pm';}, -     Z: function(date){ -          var offset = date.getTimezoneOffset(); -          return padNumber(offset / 60, 2) + padNumber(Math.abs(offset % 60), 2); -        } +     z: timeZoneGetter(false), +     Z: timeZoneGetter(true)  }; +var DEFAULT_DATETIME_FORMATS = { +         long: 'MMMM d, y h:mm:ss a z', +       medium: 'MMM d, y h:mm:ss a', +        short: 'M/d/yy h:mm a', +    fullDate: 'EEEE, MMMM d, y', +    longDate: 'MMMM d, y', +  mediumDate: 'MMM d, y', +   shortDate: 'M/d/yy', +    longTime: 'h:mm:ss a z', +  mediumTime: 'h:mm:ss a', +   shortTime: 'h:mm a' +}; -var DATE_FORMATS_SPLIT = /([^yMdHhmsaZE]*)(E+|y+|M+|d+|H+|h+|m+|s+|a|Z)(.*)/; +var GET_TIME_ZONE = /[A-Z]{3}(?![+\-])/; +var DATE_FORMATS_SPLIT = /([^yMdHhmsazZE]*)(E+|y+|M+|d+|H+|h+|m+|s+|a|Z|z)(.*)/; +var OPERA_TOSTRING_PATTERN = /^[\d].*Z$/;  var NUMBER_STRING = /^\d+$/; @@ -231,9 +255,10 @@ var NUMBER_STRING = /^\d+$/;   *   *   `format` string can be composed of the following elements:   * - *   * `'yyyy'`: 4 digit representation of year e.g. 2010 - *   * `'yy'`: 2 digit representation of year, padded (00-99) - *   * `'MMMMM'`: Month in year (January‒December) + *   * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010) + *   * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) + *   * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199) + *   * `'MMMM'`: Month in year (January‒December)   *   * `'MMM'`: Month in year (Jan - Dec)   *   * `'MM'`: Month in year, padded (01‒12)   *   * `'M'`: Month in year (1‒12) @@ -251,15 +276,36 @@ var NUMBER_STRING = /^\d+$/;   *   * `'s'`: Second in minute (0‒59)   *   * `'a'`: am/pm marker   *   * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200‒1200) + *   * `'z'`: short form of current timezone name (e.g. PDT) + * + *   `format` string can also be the following default formats for `en_US` locale (support for other + *    locales will be added in the future versions): + * + *   * `'long'`: equivalent to `'MMMM d, y h:mm:ss a z'` for en_US  locale + *     (e.g. September 3, 2010 12:05:08 pm PDT) + *   * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale + *     (e.g. Sep 3, 2010 12:05:08 pm) + *   * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US  locale (e.g. 9/3/10 12:05 pm) + *   * `'fullDate'`: equivalent to `'EEEE, MMMM d,y'` for en_US  locale + *     (e.g. Friday, September 3, 2010) + *   * `'longDate'`: equivalent to `'MMMM d, y'` for en_US  locale (e.g. September 3, 2010 + *   * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US  locale (e.g. Sep 3, 2010) + *   * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10) + *   * `'longTime'`: equivalent to `'h:mm:ss a z'` for en_US locale (e.g. 12:05:08 pm PDT) + *   * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 pm) + *   * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 pm)   *   * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or   *    number) or ISO 8601 extended datetime string (yyyy-MM-ddTHH:mm:ss.SSSZ). - * @param {string=} format Formatting rules. If not specified, Date#toLocaleDateString is used. + * @param {string=} format Formatting rules (see Description). If not specified, + *    Date#toLocaleDateString is used.   * @returns {string} Formatted string or the input if input is not recognized as date/millis.   *   * @example     <doc:example>       <doc:source> +       <span ng:non-bindable>{{1288323623006 | date:'medium'}}</span>: +           {{1288323623006 | date:'medium'}}<br/>         <span ng:non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:            {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}<br/>         <span ng:non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>: @@ -267,6 +313,8 @@ var NUMBER_STRING = /^\d+$/;       </doc:source>       <doc:scenario>         it('should format date', function(){ +         expect(binding("1288323623006 | date:'medium'")). +            toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} pm/);           expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).              toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} \-?\d{4}/);           expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")). @@ -276,6 +324,7 @@ var NUMBER_STRING = /^\d+$/;     </doc:example>   */  angularFilter.date = function(date, format) { +  format = DEFAULT_DATETIME_FORMATS[format] || format;    if (isString(date)) {      if (NUMBER_STRING.test(date)) {        date = parseInt(date, 10); diff --git a/test/FiltersSpec.js b/test/FiltersSpec.js index 594428f6..6bcdb511 100644 --- a/test/FiltersSpec.js +++ b/test/FiltersSpec.js @@ -111,8 +111,10 @@ describe('filter', function() {      });      it('should handle mailto:', function() { -      expect(linky("mailto:me@example.com").html).toEqual('<a href="mailto:me@example.com">me@example.com</a>'); -      expect(linky("me@example.com").html).toEqual('<a href="mailto:me@example.com">me@example.com</a>'); +      expect(linky("mailto:me@example.com").html). +                      toEqual('<a href="mailto:me@example.com">me@example.com</a>'); +      expect(linky("me@example.com").html). +                      toEqual('<a href="mailto:me@example.com">me@example.com</a>');        expect(linky("send email to me@example.com, but").html).          toEqual('send email to <a href="mailto:me@example.com">me@example.com</a>, but');      }); @@ -123,6 +125,9 @@ describe('filter', function() {      var morning  = new TzDate(+5, '2010-09-03T12:05:08.000Z'); //7am      var noon =     new TzDate(+5, '2010-09-03T17:05:08.000Z'); //12pm      var midnight = new TzDate(+5, '2010-09-03T05:05:08.000Z'); //12am +    var earlyDate = new TzDate(+5, '0001-09-03T05:05:08.000Z'); +    var timZoneDate = new TzDate(+5, '2010-09-03T05:05:08.000Z', +                                     'Mon Sep 3 2010 00:05:08 GMT+0500 (XYZ)'); //12am      it('should ignore falsy inputs', function() {        expect(filter.date(null)).toBeNull(); @@ -141,24 +146,79 @@ describe('filter', function() {      it('should accept various format strings', function() {        expect(filter.date(morning, "yy-MM-dd HH:mm:ss")). -                           toEqual('10-09-03 07:05:08'); +                      toEqual('10-09-03 07:05:08');        expect(filter.date(midnight, "yyyy-M-d h=H:m:saZ")). -                           toEqual('2010-9-3 12=0:5:8am0500'); +                      toEqual('2010-9-3 12=0:5:8am0500');        expect(filter.date(midnight, "yyyy-MM-dd hh=HH:mm:ssaZ")). -                           toEqual('2010-09-03 12=00:05:08am0500'); +                      toEqual('2010-09-03 12=00:05:08am0500');        expect(filter.date(noon, "yyyy-MM-dd hh=HH:mm:ssaZ")). -                       toEqual('2010-09-03 12=12:05:08pm0500'); +                      toEqual('2010-09-03 12=12:05:08pm0500'); + +      expect(filter.date(timZoneDate, "yyyy-MM-dd hh=HH:mm:ss a z")). +                      toEqual('2010-09-03 12=00:05:08 am XYZ');        expect(filter.date(noon, "EEE, MMM d, yyyy")). -                       toEqual('Fri, Sep 3, 2010'); +                      toEqual('Fri, Sep 3, 2010'); + +      expect(filter.date(noon, "EEEE, MMMM dd, yyyy")). +                      toEqual('Friday, September 03, 2010'); + +      expect(filter.date(earlyDate, "MMMM dd, y")). +                      toEqual('September 03, 1'); +    }); + +    it('should accept default formats', function() { + +      expect(filter.date(timZoneDate, "long")). +                      toEqual('September 3, 2010 12:05:08 am XYZ'); + +      expect(filter.date(noon, "medium")). +                      toEqual('Sep 3, 2010 12:05:08 pm'); + +      expect(filter.date(noon, "short")). +                      toEqual('9/3/10 12:05 pm'); + +      expect(filter.date(noon, "fullDate")). +                      toEqual('Friday, September 3, 2010'); + +      expect(filter.date(noon, "longDate")). +                      toEqual('September 3, 2010'); -      expect(filter.date(noon, "EEEE, MMMMM dd, yyyy")). -                       toEqual('Friday, September 03, 2010'); +      expect(filter.date(noon, "mediumDate")). +                      toEqual('Sep 3, 2010'); + +      expect(filter.date(noon, "shortDate")). +                      toEqual('9/3/10'); + +      expect(filter.date(timZoneDate, "longTime")). +                      toEqual('12:05:08 am XYZ'); + +      expect(filter.date(noon, "mediumTime")). +                      toEqual('12:05:08 pm'); + +      expect(filter.date(noon, "shortTime")). +                      toEqual('12:05 pm'); +    }); + + +    it('should parse timezone identifier from various toString values', function() { +      //chrome and firefox format +      expect(filter.date(new TzDate(+5, '2010-09-03T17:05:08.000Z', +                                    'Mon Sep 3 2010 17:05:08 GMT+0500 (XYZ)'), "z")).toBe('XYZ'); + +      //opera format +      expect(filter.date(new TzDate(+5, '2010-09-03T17:05:08.000Z', +                                    '2010-09-03T17:05:08Z'), "z")).toBe('0500'); + +      //ie 8 format +      expect(filter.date(new TzDate(+5, '2010-09-03T17:05:08.000Z', +                                    'Mon Sep 3 17:05:08 XYZ 2010'), "z")).toBe('XYZ');      }); +      it('should be able to parse ISO 8601 dates/times using', function() {        var isoString = '2010-09-03T05:05:08.872Z';        expect(filter.date(isoString)). diff --git a/test/angular-mocksSpec.js b/test/angular-mocksSpec.js index b85503e6..a30c3497 100644 --- a/test/angular-mocksSpec.js +++ b/test/angular-mocksSpec.js @@ -130,13 +130,9 @@ describe('mocks', function(){      it('should throw error when no third param but toString called', function() { -      var t = new TzDate(0, 0); -      try { -        t.toString(); -       } catch(err) { -         expect(err.name).toBe('MethodNotImplemented'); -       } -    }) +      expect(function() { new TzDate(0,0).toString() }). +                           toThrow('Method \'toString\' is not implemented in the TzDate mock'); +    });    });    describe('$log mock', function() { | 
