From 35a06cca8cfc2eebccc1d8329df93a713557cef8 Mon Sep 17 00:00:00 2001 From: Wesley Cho Date: Fri, 6 Nov 2015 08:11:39 -0800 Subject: [PATCH] feat(dateparser): add Z support - Add support for the `Z` format, as referred to in the Angular documentation [here](https://docs.angularjs.org/api/ng/filter/date) --- src/dateparser/dateparser.js | 57 +++++++++++++++++++++----- src/dateparser/docs/README.md | 4 ++ src/dateparser/test/dateparser.spec.js | 10 +++++ 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/dateparser/dateparser.js b/src/dateparser/dateparser.js index 195eab1680..2f57328856 100644 --- a/src/dateparser/dateparser.js +++ b/src/dateparser/dateparser.js @@ -133,6 +133,18 @@ angular.module('ui.bootstrap.dateparser', []) this.hours += 12; } } + }, + { + key: 'Z', + regex: '[+-]\\d{4}', + apply: function(value) { + var matches = value.match(/([+-])(\d{2})(\d{2})/), + sign = matches[1], + hours = matches[2], + minutes = matches[3]; + this.hours += toInt(sign + hours); + this.minutes += toInt(sign + minutes); + } } ]; }; @@ -185,7 +197,11 @@ angular.module('ui.bootstrap.dateparser', []) } format = format.join(''); - map.push({ index: index, apply: data.apply }); + map.push({ + index: index, + apply: data.apply, + matcher: data.regex + }); } }); @@ -214,15 +230,19 @@ angular.module('ui.bootstrap.dateparser', []) var parser = this.parsers[format], regex = parser.regex, map = parser.map, - results = input.match(regex); - + results = input.match(regex), + tzOffset = false; if (results && results.length) { var fields, dt; if (angular.isDate(baseDate) && !isNaN(baseDate.getTime())) { fields = { year: baseDate.getFullYear(), month: baseDate.getMonth(), - date: baseDate.getDate() + date: baseDate.getDate(), + hours: baseDate.getHours(), + minutes: baseDate.getMinutes(), + seconds: baseDate.getSeconds(), + milliseconds: baseDate.getMilliseconds() }; } else { if (baseDate) { @@ -232,21 +252,32 @@ angular.module('ui.bootstrap.dateparser', []) } for (var i = 1, n = results.length; i < n; i++) { - var mapper = map[i-1]; + var mapper = map[i - 1]; + if (mapper.matcher === 'Z') { + tzOffset = true; + } + if (mapper.apply) { mapper.apply.call(fields, results[i]); } } + var datesetter = tzOffset ? Date.prototype.setUTCFullYear : + Date.prototype.setFullYear; + var timesetter = tzOffset ? Date.prototype.setUTCHours : + Date.prototype.setHours; + if (isValid(fields.year, fields.month, fields.date)) { - if (angular.isDate(baseDate) && !isNaN(baseDate.getTime())) { + if (angular.isDate(baseDate) && !isNaN(baseDate.getTime()) && !tzOffset) { dt = new Date(baseDate); - dt.setFullYear(fields.year, fields.month, fields.date); + datesetter.call(dt, fields.year, fields.month, fields.date); + timesetter.call(dt, fields.hours, fields.minutes, + fields.seconds, fields.milliseconds); } else { - dt = new Date(fields.year, fields.month, fields.date, - fields.hours, fields.minutes, fields.seconds, - fields.milliseconds || 0); - dt.setFullYear(fields.year); + dt = new Date(0); + datesetter.call(dt, fields.year, fields.month, fields.date); + timesetter.call(dt, fields.hours || 0, fields.minutes || 0, + fields.seconds || 0, fields.milliseconds || 0); } } @@ -271,4 +302,8 @@ angular.module('ui.bootstrap.dateparser', []) return true; } + + function toInt(str) { + return parseInt(str, 10); + } }]); diff --git a/src/dateparser/docs/README.md b/src/dateparser/docs/README.md index 414eace070..d78104bb5d 100644 --- a/src/dateparser/docs/README.md +++ b/src/dateparser/docs/README.md @@ -117,6 +117,10 @@ Certain format codes support i18n. Check this [guide](https://docs.angularjs.org * `a` _(Example: `10AM`)_ - Parses a 12 hours time with AM/PM. + +* `Z' + _(Example: `-0800`)_ - + Parses the timezone offset in a signed 4 digit representation \* The ones marked with `Leading 0`, needs a leading 0 for values less than 10. Exception being milliseconds which needs it for values under 100. diff --git a/src/dateparser/test/dateparser.spec.js b/src/dateparser/test/dateparser.spec.js index 1155ca6e7f..3ad8341332 100644 --- a/src/dateparser/test/dateparser.spec.js +++ b/src/dateparser/test/dateparser.spec.js @@ -224,6 +224,16 @@ describe('date parser', function() { expectParse('11-08-13 09AM', 'd-MM-yy hha', new Date(2013, 7, 11, 9)); expectParse('11-08-13 09PM', 'd-MM-yy hha', new Date(2013, 7, 11, 21)); }); + + it('should work correctly for `Z`', function() { + expectParse('22.March.15 -0700', 'd.MMMM.yy Z', new Date(2015, 2, 21, 17, 0, 0)); + expectParse('8-March-1991 +0800', 'd-MMMM-yyyy Z', new Date(1991, 2, 8, 8, 0, 0)); + expectParse('February/5/1980 -0200', 'MMMM/d/yyyy Z', new Date(1980, 1, 4, 22, 0, 0)); + expectParse('1955/February/5 +0400', 'yyyy/MMMM/d Z', new Date(1955, 1, 5, 4, 0, 0)); + expectParse('11-08-13 -1234', 'd-MM-yy Z', new Date(2013, 7, 10, 11, 26, 0)); + expectParse('22.March.15.22:33:4 -1200', 'd.MMMM.yy.HH:mm:s Z', new Date(2015, 2, 22, 10, 33, 4)); + expectParse('22.March.15.22:3:4 +1500', 'd.MMMM.yy.HH:m:s Z', new Date(2015, 2, 23, 13, 3, 4)); + }); }); describe('with predefined formats', function() {