diff --git a/src/dateparser/dateparser.js b/src/dateparser/dateparser.js index 732b509587..b53d97c646 100644 --- a/src/dateparser/dateparser.js +++ b/src/dateparser/dateparser.js @@ -111,6 +111,35 @@ angular.module('ui.bootstrap.dateparser', []) function createParser(format) { var map = [], regex = format.split(''); + // check for literal values + var quoteIndex = format.indexOf('\''); + if (quoteIndex > -1) { + var inLiteral = false; + format = format.split(''); + for (var i = quoteIndex; i < format.length; i++) { + if (inLiteral) { + if (format[i] === '\'') { + if (i + 1 < format.length && format[i+1] === '\'') { // escaped single quote + format[i+1] = '$'; + regex[i+1] = ''; + } else { // end of literal + regex[i] = ''; + inLiteral = false; + } + } + format[i] = '$'; + } else { + if (format[i] === '\'') { // start of literal + format[i] = '$'; + regex[i] = ''; + inLiteral = true; + } + } + } + + format = format.join(''); + } + angular.forEach(formatCodeToRegex, function(data, code) { var index = format.indexOf(code); diff --git a/src/dateparser/test/dateparser.spec.js b/src/dateparser/test/dateparser.spec.js index d76000a73e..2773a20f2a 100644 --- a/src/dateparser/test/dateparser.spec.js +++ b/src/dateparser/test/dateparser.spec.js @@ -204,6 +204,28 @@ describe('date parser', function() { }); }); + describe('with value literals', function() { + it('should work with multiple literals', function() { + expect(dateParser.parse('29 de January de 2013', 'd \'de\' MMMM \'de\' y')).toEqual(new Date(2013, 0, 29)); + }); + + it('should work with escaped single quote', function() { + expect(dateParser.parse('22.March.15 12 o\'clock', 'd.MMMM.yy h \'o\'\'clock\'')).toEqual(new Date(2015, 2, 22, 12)); + }); + + it('should work with only a single quote', function() { + expect(dateParser.parse('22.March.15 \'', 'd.MMMM.yy \'\'\'')).toEqual(new Date(2015, 2, 22)); + }); + + it('should work with trailing literal', function() { + expect(dateParser.parse('year 2013', '\'year\' y')).toEqual(new Date(2013, 0, 1)); + }); + + it('should work without whitespace', function() { + expect(dateParser.parse('year:2013', '\'year:\'y')).toEqual(new Date(2013, 0, 1)); + }); + }); + describe('with edge case', function() { it('should not work for invalid number of days in February', function() { expectParse('29.02.2013', 'dd.MM.yyyy', undefined); diff --git a/src/datepicker/docs/readme.md b/src/datepicker/docs/readme.md index 956032a04c..94875c2b50 100644 --- a/src/datepicker/docs/readme.md +++ b/src/datepicker/docs/readme.md @@ -28,7 +28,7 @@ All settings can be provided as attributes in the `uib-datepicker` or globally c * `date-disabled (date, mode)` _(Default: null)_ : An optional expression to disable visible options based on passing date and current mode _(day|month|year)_. - + * `custom-class (date, mode)` _(Default: null)_ : An optional expression to add classes based on passing date and current mode _(day|month|year)_. @@ -79,7 +79,7 @@ All settings can be provided as attributes in the `uib-datepicker` or globally c * `year-range` _(Default: 20)_ : - Number of years displayed in year selection. + Number of years displayed in year selection. * `shortcut-propagation` _(Default: false)_ : @@ -97,7 +97,7 @@ Specific settings for the `uib-datepicker-popup`, that can globally configured t * `uib-datepicker-popup` _(Default: 'yyyy-MM-dd')_ : - The format for displayed dates. + The format for displayed dates. This string can take string literals by surrounding the value with single quotes, i.e. `yyyy-MM-dd h 'o\'clock'` * `show-button-bar` _(Default: true)_ : @@ -154,4 +154,4 @@ Depending on datepicker's current mode, the date may refer either to day, month * `Enter`/`Space`: Select date. * `Ctrl`+`Up`: Move to an upper mode. * `Ctrl`+`Down`: Move to a lower mode. - * `Esc`: Will close popup, and move focus to the input. \ No newline at end of file + * `Esc`: Will close popup, and move focus to the input.