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

Commit

Permalink
fix(dateparser): correctly format with literals
Browse files Browse the repository at this point in the history
- Fix formatting of dates with literal usage

Closes #6055
Fixes #5620
Fixes #5802
  • Loading branch information
wesleycho committed Jun 27, 2016
1 parent 409b7aa commit d846e2d
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 42 deletions.
91 changes: 70 additions & 21 deletions src/dateparser/dateparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ angular.module('ui.bootstrap.dateparser', [])

this.init();

function createParser(format, func) {
function createParser(format) {
var map = [], regex = format.split('');

// check for literal values
Expand Down Expand Up @@ -283,7 +283,7 @@ angular.module('ui.bootstrap.dateparser', [])
map.push({
index: index,
key: data.key,
apply: data[func],
apply: data.apply,
matcher: data.regex
});
}
Expand All @@ -295,6 +295,70 @@ angular.module('ui.bootstrap.dateparser', [])
};
}

function createFormatter(format) {
var formatters = [];
var i = 0;
var formatter, literalIdx;
while (i < format.length) {
if (angular.isNumber(literalIdx)) {
if (format.charAt(i) === '\'') {
if (i + 1 >= format.length || format.charAt(i + 1) !== '\'') {
formatters.push(constructLiteralFormatter(format, literalIdx, i));
literalIdx = null;
}
} else if (i === format.length) {
while (literalIdx < format.length) {
formatter = constructFormatterFromIdx(format, literalIdx);
formatters.push(formatter);
literalIdx = formatter.endIdx;
}
}

i++;
continue;
}

if (format.charAt(i) === '\'') {
literalIdx = i;
i++;
continue;
}

formatter = constructFormatterFromIdx(format, i);

formatters.push(formatter.parser);
i = formatter.endIdx;
}

return formatters;
}

function constructLiteralFormatter(format, literalIdx, endIdx) {
return function() {
return format.substr(literalIdx + 1, endIdx - literalIdx - 1);
};
}

function constructFormatterFromIdx(format, i) {
var currentPosStr = format.substr(i);
for (var j = 0; j < formatCodeToRegex.length; j++) {
if (new RegExp('^' + formatCodeToRegex[j].key).test(currentPosStr)) {
var data = formatCodeToRegex[j];
return {
endIdx: i + data.key.length,
parser: data.formatter
};
}
}

return {
endIdx: i + 1,
parser: function() {
return currentPosStr.charAt(0);
}
};
}

this.filter = function(date, format) {
if (!angular.isDate(date) || isNaN(date) || !format) {
return '';
Expand All @@ -307,28 +371,13 @@ angular.module('ui.bootstrap.dateparser', [])
}

if (!this.formatters[format]) {
this.formatters[format] = createParser(format, 'formatter');
this.formatters[format] = createFormatter(format);
}

var parser = this.formatters[format],
map = parser.map;

var _format = format;

return map.reduce(function(str, mapper, i) {
var match = _format.match(new RegExp('(.*)' + mapper.key));
if (match && angular.isString(match[1])) {
str += match[1];
_format = _format.replace(match[1] + mapper.key, '');
}

var endStr = i === map.length - 1 ? _format : '';

if (mapper.apply) {
return str + mapper.apply.call(null, date) + endStr;
}
var formatters = this.formatters[format];

return str + endStr;
return formatters.reduce(function(str, formatter) {
return str + formatter(date);
}, '');
};

Expand Down
42 changes: 21 additions & 21 deletions src/dateparser/test/dateparser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -565,27 +565,27 @@ describe('date parser', function() {
});

describe('with value literals', function() {
// describe('filter', function() {
// it('should work with multiple literals', function() {
// expect(dateParser.filter(new Date(2013, 0, 29), 'd \'de\' MMMM \'de\' y')).toEqual('29 de January de 2013');
// });
//
// it('should work with escaped single quote', function() {
// expect(dateParser.filter(new Date(2015, 2, 22, 12), 'd.MMMM.yy h \'o\'\'clock\'')).toEqual('22.March.15 12 o\'clock');
// });
//
// it('should work with only a single quote', function() {
// expect(dateParser.filter(new Date(2015, 2, 22), 'd.MMMM.yy \'\'\'')).toEqual('22.March.15 \'');
// });
//
// it('should work with trailing literal', function() {
// expect(dateParser.filter(new Date(2013, 0, 1), '\'year\' y')).toEqual('year 2013');
// });
//
// it('should work without whitespace', function() {
// expect(dateParser.filter(new Date(2013, 0, 1), '\'year:\'y')).toEqual('year:2013');
// });
// });
describe('filter', function() {
it('should work with multiple literals', function() {
expect(dateParser.filter(new Date(2013, 0, 29), 'd \'de\' MMMM \'de\' y')).toEqual('29 de January de 2013');
});

it('should work with escaped single quote', function() {
expect(dateParser.filter(new Date(2015, 2, 22, 12), 'd.MMMM.yy h \'o\'\'clock\'')).toEqual('22.March.15 12 o\'clock');
});

it('should work with only a single quote', function() {
expect(dateParser.filter(new Date(2015, 2, 22), 'd.MMMM.yy \'\'\'')).toEqual('22.March.15 \'');
});

it('should work with trailing literal', function() {
expect(dateParser.filter(new Date(2013, 0, 1), '\'year\' y')).toEqual('year 2013');
});

it('should work without whitespace', function() {
expect(dateParser.filter(new Date(2013, 0, 1), '\'year:\'y')).toEqual('year:2013');
});
});

describe('parse', function() {
it('should work with multiple literals', function() {
Expand Down

0 comments on commit d846e2d

Please sign in to comment.