Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit 2fb812b

Browse files
committed
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) Closes #4831
1 parent 628039b commit 2fb812b

File tree

3 files changed

+60
-11
lines changed

3 files changed

+60
-11
lines changed

src/dateparser/dateparser.js

+46-11
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,18 @@ angular.module('ui.bootstrap.dateparser', [])
133133
this.hours += 12;
134134
}
135135
}
136+
},
137+
{
138+
key: 'Z',
139+
regex: '[+-]\\d{4}',
140+
apply: function(value) {
141+
var matches = value.match(/([+-])(\d{2})(\d{2})/),
142+
sign = matches[1],
143+
hours = matches[2],
144+
minutes = matches[3];
145+
this.hours += toInt(sign + hours);
146+
this.minutes += toInt(sign + minutes);
147+
}
136148
}
137149
];
138150
};
@@ -185,7 +197,11 @@ angular.module('ui.bootstrap.dateparser', [])
185197
}
186198
format = format.join('');
187199

188-
map.push({ index: index, apply: data.apply });
200+
map.push({
201+
index: index,
202+
apply: data.apply,
203+
matcher: data.regex
204+
});
189205
}
190206
});
191207

@@ -214,15 +230,19 @@ angular.module('ui.bootstrap.dateparser', [])
214230
var parser = this.parsers[format],
215231
regex = parser.regex,
216232
map = parser.map,
217-
results = input.match(regex);
218-
233+
results = input.match(regex),
234+
tzOffset = false;
219235
if (results && results.length) {
220236
var fields, dt;
221237
if (angular.isDate(baseDate) && !isNaN(baseDate.getTime())) {
222238
fields = {
223239
year: baseDate.getFullYear(),
224240
month: baseDate.getMonth(),
225-
date: baseDate.getDate()
241+
date: baseDate.getDate(),
242+
hours: baseDate.getHours(),
243+
minutes: baseDate.getMinutes(),
244+
seconds: baseDate.getSeconds(),
245+
milliseconds: baseDate.getMilliseconds()
226246
};
227247
} else {
228248
if (baseDate) {
@@ -232,21 +252,32 @@ angular.module('ui.bootstrap.dateparser', [])
232252
}
233253

234254
for (var i = 1, n = results.length; i < n; i++) {
235-
var mapper = map[i-1];
255+
var mapper = map[i - 1];
256+
if (mapper.matcher === 'Z') {
257+
tzOffset = true;
258+
}
259+
236260
if (mapper.apply) {
237261
mapper.apply.call(fields, results[i]);
238262
}
239263
}
240264

265+
var datesetter = tzOffset ? Date.prototype.setUTCFullYear :
266+
Date.prototype.setFullYear;
267+
var timesetter = tzOffset ? Date.prototype.setUTCHours :
268+
Date.prototype.setHours;
269+
241270
if (isValid(fields.year, fields.month, fields.date)) {
242-
if (angular.isDate(baseDate) && !isNaN(baseDate.getTime())) {
271+
if (angular.isDate(baseDate) && !isNaN(baseDate.getTime()) && !tzOffset) {
243272
dt = new Date(baseDate);
244-
dt.setFullYear(fields.year, fields.month, fields.date);
273+
datesetter.call(dt, fields.year, fields.month, fields.date);
274+
timesetter.call(dt, fields.hours, fields.minutes,
275+
fields.seconds, fields.milliseconds);
245276
} else {
246-
dt = new Date(fields.year, fields.month, fields.date,
247-
fields.hours, fields.minutes, fields.seconds,
248-
fields.milliseconds || 0);
249-
dt.setFullYear(fields.year);
277+
dt = new Date(0);
278+
datesetter.call(dt, fields.year, fields.month, fields.date);
279+
timesetter.call(dt, fields.hours || 0, fields.minutes || 0,
280+
fields.seconds || 0, fields.milliseconds || 0);
250281
}
251282
}
252283

@@ -271,4 +302,8 @@ angular.module('ui.bootstrap.dateparser', [])
271302

272303
return true;
273304
}
305+
306+
function toInt(str) {
307+
return parseInt(str, 10);
308+
}
274309
}]);

src/dateparser/docs/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ Certain format codes support i18n. Check this [guide](https://docs.angularjs.org
117117
* `a`
118118
_(Example: `10AM`)_ -
119119
Parses a 12 hours time with AM/PM.
120+
121+
* `Z'
122+
_(Example: `-0800`)_ -
123+
Parses the timezone offset in a signed 4 digit representation
120124

121125
\* 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.
122126

src/dateparser/test/dateparser.spec.js

+10
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,16 @@ describe('date parser', function() {
224224
expectParse('11-08-13 09AM', 'd-MM-yy hha', new Date(2013, 7, 11, 9));
225225
expectParse('11-08-13 09PM', 'd-MM-yy hha', new Date(2013, 7, 11, 21));
226226
});
227+
228+
it('should work correctly for `Z`', function() {
229+
expectParse('22.March.15 -0700', 'd.MMMM.yy Z', new Date(2015, 2, 21, 17, 0, 0));
230+
expectParse('8-March-1991 +0800', 'd-MMMM-yyyy Z', new Date(1991, 2, 8, 8, 0, 0));
231+
expectParse('February/5/1980 -0200', 'MMMM/d/yyyy Z', new Date(1980, 1, 4, 22, 0, 0));
232+
expectParse('1955/February/5 +0400', 'yyyy/MMMM/d Z', new Date(1955, 1, 5, 4, 0, 0));
233+
expectParse('11-08-13 -1234', 'd-MM-yy Z', new Date(2013, 7, 10, 11, 26, 0));
234+
expectParse('22.March.15.22:33:4 -1200', 'd.MMMM.yy.HH:mm:s Z', new Date(2015, 2, 22, 10, 33, 4));
235+
expectParse('22.March.15.22:3:4 +1500', 'd.MMMM.yy.HH:m:s Z', new Date(2015, 2, 23, 13, 3, 4));
236+
});
227237
});
228238

229239
describe('with predefined formats', function() {

0 commit comments

Comments
 (0)