diff --git a/src/dateparser/dateparser.js b/src/dateparser/dateparser.js index deaf548d39..cb4a8290c9 100644 --- a/src/dateparser/dateparser.js +++ b/src/dateparser/dateparser.js @@ -1,6 +1,6 @@ angular.module('ui.bootstrap.dateparser', []) -.service('uibDateParser', ['$log', '$locale', 'orderByFilter', function($log, $locale, orderByFilter) { +.service('uibDateParser', ['$log', '$locale', 'dateFilter', 'orderByFilter', function($log, $locale, dateFilter, orderByFilter) { // Pulled from https://github.com/mbostock/d3/blob/master/src/format/requote.js var SPECIAL_CHARACTERS_REGEXP = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; @@ -11,115 +11,164 @@ angular.module('ui.bootstrap.dateparser', []) localeId = $locale.id; this.parsers = {}; + this.formatters = {}; formatCodeToRegex = [ { key: 'yyyy', regex: '\\d{4}', - apply: function(value) { this.year = +value; } + apply: function(value) { this.year = +value; }, + formatter: function(date) { + var _date = new Date(); + _date.setFullYear(Math.abs(date.getFullYear())); + return dateFilter(_date, 'yyyy'); + } }, { key: 'yy', regex: '\\d{2}', - apply: function(value) { this.year = +value + 2000; } + apply: function(value) { this.year = +value + 2000; }, + formatter: function(date) { + var _date = new Date(); + _date.setFullYear(Math.abs(date.getFullYear())); + return dateFilter(_date, 'yy'); + } }, { key: 'y', regex: '\\d{1,4}', - apply: function(value) { this.year = +value; } + apply: function(value) { this.year = +value; }, + formatter: function(date) { + var _date = new Date(); + _date.setFullYear(Math.abs(date.getFullYear())); + return dateFilter(_date, 'y'); + } }, { key: 'M!', regex: '0?[1-9]|1[0-2]', - apply: function(value) { this.month = value - 1; } + apply: function(value) { this.month = value - 1; }, + formatter: function(date) { + var value = date.getMonth(); + if (/^[0-9]$/.test(value)) { + return dateFilter(date, 'MM'); + } + + return dateFilter(date, 'M'); + } }, { key: 'MMMM', regex: $locale.DATETIME_FORMATS.MONTH.join('|'), - apply: function(value) { this.month = $locale.DATETIME_FORMATS.MONTH.indexOf(value); } + apply: function(value) { this.month = $locale.DATETIME_FORMATS.MONTH.indexOf(value); }, + formatter: function(date) { return dateFilter(date, 'MMMM'); } }, { key: 'MMM', regex: $locale.DATETIME_FORMATS.SHORTMONTH.join('|'), - apply: function(value) { this.month = $locale.DATETIME_FORMATS.SHORTMONTH.indexOf(value); } + apply: function(value) { this.month = $locale.DATETIME_FORMATS.SHORTMONTH.indexOf(value); }, + formatter: function(date) { return dateFilter(date, 'MMM'); } }, { key: 'MM', regex: '0[1-9]|1[0-2]', - apply: function(value) { this.month = value - 1; } + apply: function(value) { this.month = value - 1; }, + formatter: function(date) { return dateFilter(date, 'MM'); } }, { key: 'M', regex: '[1-9]|1[0-2]', - apply: function(value) { this.month = value - 1; } + apply: function(value) { this.month = value - 1; }, + formatter: function(date) { return dateFilter(date, 'M'); } }, { key: 'd!', regex: '[0-2]?[0-9]{1}|3[0-1]{1}', - apply: function(value) { this.date = +value; } + apply: function(value) { this.date = +value; }, + formatter: function(date) { + var value = date.getDate(); + if (/^[1-9]$/.test(value)) { + return dateFilter(date, 'dd'); + } + + return dateFilter(date, 'd'); + } }, { key: 'dd', regex: '[0-2][0-9]{1}|3[0-1]{1}', - apply: function(value) { this.date = +value; } + apply: function(value) { this.date = +value; }, + formatter: function(date) { return dateFilter(date, 'dd'); } }, { key: 'd', regex: '[1-2]?[0-9]{1}|3[0-1]{1}', - apply: function(value) { this.date = +value; } + apply: function(value) { this.date = +value; }, + formatter: function(date) { return dateFilter(date, 'd'); } }, { key: 'EEEE', - regex: $locale.DATETIME_FORMATS.DAY.join('|') + regex: $locale.DATETIME_FORMATS.DAY.join('|'), + formatter: function(date) { return dateFilter(date, 'EEEE'); } }, { key: 'EEE', - regex: $locale.DATETIME_FORMATS.SHORTDAY.join('|') + regex: $locale.DATETIME_FORMATS.SHORTDAY.join('|'), + formatter: function(date) { return dateFilter(date, 'EEE'); } }, { key: 'HH', regex: '(?:0|1)[0-9]|2[0-3]', - apply: function(value) { this.hours = +value; } + apply: function(value) { this.hours = +value; }, + formatter: function(date) { return dateFilter(date, 'HH'); } }, { key: 'hh', regex: '0[0-9]|1[0-2]', - apply: function(value) { this.hours = +value; } + apply: function(value) { this.hours = +value; }, + formatter: function(date) { return dateFilter(date, 'hh'); } }, { key: 'H', regex: '1?[0-9]|2[0-3]', - apply: function(value) { this.hours = +value; } + apply: function(value) { this.hours = +value; }, + formatter: function(date) { return dateFilter(date, 'H'); } }, { key: 'h', regex: '[0-9]|1[0-2]', - apply: function(value) { this.hours = +value; } + apply: function(value) { this.hours = +value; }, + formatter: function(date) { return dateFilter(date, 'h'); } }, { key: 'mm', regex: '[0-5][0-9]', - apply: function(value) { this.minutes = +value; } + apply: function(value) { this.minutes = +value; }, + formatter: function(date) { return dateFilter(date, 'mm'); } }, { key: 'm', regex: '[0-9]|[1-5][0-9]', - apply: function(value) { this.minutes = +value; } + apply: function(value) { this.minutes = +value; }, + formatter: function(date) { return dateFilter(date, 'm'); } }, { key: 'sss', regex: '[0-9][0-9][0-9]', - apply: function(value) { this.milliseconds = +value; } + apply: function(value) { this.milliseconds = +value; }, + formatter: function(date) { return dateFilter(date, 'sss'); } }, { key: 'ss', regex: '[0-5][0-9]', - apply: function(value) { this.seconds = +value; } + apply: function(value) { this.seconds = +value; }, + formatter: function(date) { return dateFilter(date, 'ss'); } }, { key: 's', regex: '[0-9]|[1-5][0-9]', - apply: function(value) { this.seconds = +value; } + apply: function(value) { this.seconds = +value; }, + formatter: function(date) { return dateFilter(date, 's'); } }, { key: 'a', @@ -132,7 +181,8 @@ angular.module('ui.bootstrap.dateparser', []) if (value === 'PM') { this.hours += 12; } - } + }, + formatter: function(date) { return dateFilter(date, 'a'); } }, { key: 'Z', @@ -144,38 +194,47 @@ angular.module('ui.bootstrap.dateparser', []) minutes = matches[3]; this.hours += toInt(sign + hours); this.minutes += toInt(sign + minutes); + }, + formatter: function(date) { + return dateFilter(date, 'Z'); } }, { key: 'ww', - regex: '[0-4][0-9]|5[0-3]' + regex: '[0-4][0-9]|5[0-3]', + formatter: function(date) { return dateFilter(date, 'ww'); } }, { key: 'w', - regex: '[0-9]|[1-4][0-9]|5[0-3]' + regex: '[0-9]|[1-4][0-9]|5[0-3]', + formatter: function(date) { return dateFilter(date, 'w'); } }, { key: 'GGGG', - regex: $locale.DATETIME_FORMATS.ERANAMES.join('|').replace(/\s/g, '\\s') + regex: $locale.DATETIME_FORMATS.ERANAMES.join('|').replace(/\s/g, '\\s'), + formatter: function(date) { return dateFilter(date, 'GGGG'); } }, { key: 'GGG', - regex: $locale.DATETIME_FORMATS.ERAS.join('|') + regex: $locale.DATETIME_FORMATS.ERAS.join('|'), + formatter: function(date) { return dateFilter(date, 'GGG'); } }, { key: 'GG', - regex: $locale.DATETIME_FORMATS.ERAS.join('|') + regex: $locale.DATETIME_FORMATS.ERAS.join('|'), + formatter: function(date) { return dateFilter(date, 'GG'); } }, { key: 'G', - regex: $locale.DATETIME_FORMATS.ERAS.join('|') + regex: $locale.DATETIME_FORMATS.ERAS.join('|'), + formatter: function(date) { return dateFilter(date, 'G'); } } ]; }; this.init(); - function createParser(format) { + function createParser(format, func) { var map = [], regex = format.split(''); // check for literal values @@ -223,7 +282,8 @@ angular.module('ui.bootstrap.dateparser', []) map.push({ index: index, - apply: data.apply, + key: data.key, + apply: data[func], matcher: data.regex }); } @@ -235,6 +295,41 @@ angular.module('ui.bootstrap.dateparser', []) }; } + this.filter = function(date, format) { + if (!angular.isDate(date) || isNaN(date) || !format) { + return ''; + } + + format = $locale.DATETIME_FORMATS[format] || format; + + if ($locale.id !== localeId) { + this.init(); + } + + if (!this.formatters[format]) { + this.formatters[format] = createParser(format, 'formatter'); + } + + 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, ''); + } + + if (mapper.apply) { + return str + mapper.apply.call(null, date); + } + + return str; + }, ''); + }; + this.parse = function(input, format, baseDate) { if (!angular.isString(input) || !format) { return input; @@ -248,7 +343,7 @@ angular.module('ui.bootstrap.dateparser', []) } if (!this.parsers[format]) { - this.parsers[format] = createParser(format); + this.parsers[format] = createParser(format, 'apply'); } var parser = this.parsers[format], @@ -336,7 +431,7 @@ angular.module('ui.bootstrap.dateparser', []) this.timezoneToOffset = timezoneToOffset; this.addDateMinutes = addDateMinutes; this.convertTimezoneToLocal = convertTimezoneToLocal; - + function toTimezone(date, timezone) { return date && timezone ? convertTimezoneToLocal(date, timezone) : date; } diff --git a/src/dateparser/test/dateparser.spec.js b/src/dateparser/test/dateparser.spec.js index 36ed89d8f4..22dff9759f 100644 --- a/src/dateparser/test/dateparser.spec.js +++ b/src/dateparser/test/dateparser.spec.js @@ -8,6 +8,10 @@ describe('date parser', function() { oldDate.setFullYear(1); })); + function expectFilter(date, format, display) { + expect(dateParser.filter(date, format)).toEqual(display); + } + function expectParse(input, format, date) { expect(dateParser.parse(input, format)).toEqual(date); } @@ -16,6 +20,249 @@ describe('date parser', function() { expect(dateParser.parse(input, format, baseDate)).toEqual(date); } + describe('filter', function() { + it('should work correctly for `dd`, `MM`, `yyyy`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'dd.MM.yyyy', '17.11.2013'); + expectFilter(new Date(2013, 11, 31, 0), 'dd.MM.yyyy', '31.12.2013'); + expectFilter(new Date(1991, 2, 8, 0), 'dd-MM-yyyy', '08-03-1991'); + expectFilter(new Date(1980, 2, 5, 0), 'MM/dd/yyyy', '03/05/1980'); + expectFilter(new Date(1983, 0, 10, 0), 'dd.MM/yyyy', '10.01/1983'); + expectFilter(new Date(1980, 10, 9, 0), 'MM-dd-yyyy', '11-09-1980'); + expectFilter(new Date(2011, 1, 5, 0), 'yyyy/MM/dd', '2011/02/05'); + expectFilter(oldDate, 'yyyy/MM/dd', '0001/03/06'); + }); + + it('should work correctly for `yy`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'dd.MM.yy', '17.11.13'); + expectFilter(new Date(2011, 4, 2, 0), 'dd-MM-yy', '02-05-11'); + expectFilter(new Date(2080, 1, 5, 0), 'MM/dd/yy', '02/05/80'); + expectFilter(new Date(2055, 1, 5, 0), 'yy/MM/dd', '55/02/05'); + expectFilter(new Date(2013, 7, 11, 0), 'dd-MM-yy', '11-08-13'); + }); + + it('should work correctly for `y`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'dd.MM.y', '17.11.2013'); + expectFilter(new Date(2013, 11, 31, 0), 'dd.MM.y', '31.12.2013'); + expectFilter(new Date(1991, 2, 8, 0), 'dd-MM-y', '08-03-1991'); + expectFilter(new Date(1980, 2, 5, 0), 'MM/dd/y', '03/05/1980'); + expectFilter(new Date(1983, 0, 10, 0), 'dd.MM/y', '10.01/1983'); + expectFilter(new Date(1980, 10, 9, 0), 'MM-dd-y', '11-09-1980'); + expectFilter(new Date(2011, 1, 5, 0), 'y/MM/dd', '2011/02/05'); + }); + + it('should work correctly for `MMMM`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'dd.MMMM.yy', '17.November.13'); + expectFilter(new Date(1980, 2, 5, 0), 'dd-MMMM-yyyy', '05-March-1980'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/dd/yyyy', 'February/05/1980'); + expectFilter(new Date(1949, 11, 20, 0), 'yyyy/MMMM/dd', '1949/December/20'); + expectFilter(oldDate, 'yyyy/MMMM/dd', '0001/March/06'); + }); + + it('should work correctly for `MMM`', function() { + expectFilter(new Date(2010, 8, 30, 0), 'dd.MMM.yy', '30.Sep.10'); + expectFilter(new Date(2011, 4, 2, 0), 'dd-MMM-yy', '02-May-11'); + expectFilter(new Date(1980, 1, 5, 0), 'MMM/dd/yyyy', 'Feb/05/1980'); + expectFilter(new Date(1955, 1, 5, 0), 'yyyy/MMM/dd', '1955/Feb/05'); + expectFilter(oldDate, 'yyyy/MMM/dd', '0001/Mar/06'); + }); + + it('should work correctly for `M`', function() { + expectFilter(new Date(2013, 7, 11, 0), 'M/dd/yyyy', '8/11/2013'); + expectFilter(new Date(2005, 10, 7, 0), 'dd.M.yy', '07.11.05'); + expectFilter(new Date(2011, 4, 2, 0), 'dd-M-yy', '02-5-11'); + expectFilter(new Date(1980, 1, 5, 0), 'M/dd/yyyy', '2/05/1980'); + expectFilter(new Date(1955, 1, 5, 0), 'yyyy/M/dd', '1955/2/05'); + expectFilter(new Date(2011, 4, 2, 0), 'dd-M-yy', '02-5-11'); + }); + + it('should work correctly for `M!`', function() { + expectFilter(new Date(2013, 7, 11, 0), 'M!/dd/yyyy', '08/11/2013'); + expectFilter(new Date(2005, 10, 7, 0), 'dd.M!.yy', '07.11.05'); + expectFilter(new Date(2011, 4, 2, 0), 'dd-M!-yy', '02-05-11'); + expectFilter(new Date(1980, 1, 5, 0), 'M!/dd/yyyy', '02/05/1980'); + expectFilter(new Date(1955, 1, 5, 0), 'yyyy/M!/dd', '1955/02/05'); + expectFilter(new Date(2011, 4, 2, 0), 'dd-M!-yy', '02-05-11'); + expectFilter(oldDate, 'yyyy/M!/dd', '0001/03/06'); + }); + + it('should work correctly for `d`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'd.MMMM.yy', '17.November.13'); + expectFilter(new Date(1991, 2, 8, 0), 'd-MMMM-yyyy', '8-March-1991'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy', 'February/5/1980'); + expectFilter(new Date(1955, 1, 5, 0), 'yyyy/MMMM/d', '1955/February/5'); + expectFilter(new Date(2013, 7, 11, 0), 'd-MM-yy', '11-08-13'); + expectFilter(oldDate, 'yyyy/MM/d', '0001/03/6'); + }); + + it('should work correctly for `d!`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'd!.MMMM.yy', '17.November.13'); + expectFilter(new Date(1991, 2, 8, 0), 'd!-MMMM-yyyy', '08-March-1991'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d!/yyyy', 'February/05/1980'); + expectFilter(new Date(1955, 1, 5, 0), 'yyyy/MMMM/d!', '1955/February/05'); + expectFilter(new Date(2013, 7, 11, 0), 'd!-MM-yy', '11-08-13'); + expectFilter(oldDate, 'yyyy/MM/d!', '0001/03/06'); + }); + + it('should work correctly for `EEEE`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'EEEE.d.MMMM.yy', 'Sunday.17.November.13'); + expectFilter(new Date(1991, 2, 8, 0), 'd-EEEE-MMMM-yyyy', '8-Friday-March-1991'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/EEEE', 'February/5/1980/Tuesday'); + expectFilter(new Date(1955, 1, 5, 0), 'yyyy/EEEE/MMMM/d', '1955/Saturday/February/5'); + }); + + it('should work correctly for `EEE`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'EEE.d.MMMM.yy', 'Sun.17.November.13'); + expectFilter(new Date(1991, 2, 8, 0), 'd-EEE-MMMM-yyyy', '8-Fri-March-1991'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/EEE', 'February/5/1980/Tue'); + expectFilter(new Date(1955, 1, 5, 0), 'yyyy/EEE/MMMM/d', '1955/Sat/February/5'); + }); + + it('should work correctly for `HH`', function() { + expectFilter(new Date(2015, 2, 22, 22), 'd.MMMM.yy.HH', '22.March.15.22'); + expectFilter(new Date(1991, 2, 8, 11), 'd-MMMM-yyyy-HH', '8-March-1991-11'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/HH', 'February/5/1980/00'); + expectFilter(new Date(1955, 1, 5, 3), 'yyyy/MMMM/d HH', '1955/February/5 03'); + expectFilter(new Date(2013, 7, 11, 23), 'd-MM-yy HH', '11-08-13 23'); + }); + + it('should work correctly for `H`', function() { + expectFilter(new Date(2015, 2, 22, 22), 'd.MMMM.yy.H', '22.March.15.22'); + expectFilter(new Date(1991, 2, 8, 11), 'd-MMMM-yyyy-H', '8-March-1991-11'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/H', 'February/5/1980/0'); + expectFilter(new Date(1955, 1, 5, 3), 'yyyy/MMMM/d H', '1955/February/5 3'); + expectFilter(new Date(2013, 7, 11, 23), 'd-MM-yy H', '11-08-13 23'); + }); + + it('should work correctly for `hh`', function() { + expectFilter(new Date(2015, 2, 22, 12), 'd.MMMM.yy.hh', '22.March.15.12'); + expectFilter(new Date(1991, 2, 8, 11), 'd-MMMM-yyyy-hh', '8-March-1991-11'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/hh', 'February/5/1980/12'); + expectFilter(new Date(1955, 1, 5, 3), 'yyyy/MMMM/d hh', '1955/February/5 03'); + expectFilter(new Date(2013, 7, 11, 9), 'd-MM-yy hh', '11-08-13 09'); + }); + + it('should work correctly for `h`', function() { + expectFilter(new Date(2015, 2, 22, 12), 'd.MMMM.yy.h', '22.March.15.12'); + expectFilter(new Date(1991, 2, 8, 11), 'd-MMMM-yyyy-h', '8-March-1991-11'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/h', 'February/5/1980/12'); + expectFilter(new Date(1955, 1, 5, 3), 'yyyy/MMMM/d h', '1955/February/5 3'); + expectFilter(new Date(2013, 7, 11, 3), 'd-MM-yy h', '11-08-13 3'); + }); + + it('should work correctly for `mm`', function() { + expectFilter(new Date(2015, 2, 22, 0, 22), 'd.MMMM.yy.mm', '22.March.15.22'); + expectFilter(new Date(1991, 2, 8, 0, 59), 'd-MMMM-yyyy-mm', '8-March-1991-59'); + expectFilter(new Date(1980, 1, 5, 0, 0), 'MMMM/d/yyyy/mm', 'February/5/1980/00'); + expectFilter(new Date(1955, 1, 5, 0, 3), 'yyyy/MMMM/d mm', '1955/February/5 03'); + expectFilter(new Date(2013, 7, 11, 0, 46), 'd-MM-yy mm', '11-08-13 46'); + expectFilter(new Date(2015, 2, 22, 22, 33), 'd.MMMM.yy.HH:mm', '22.March.15.22:33'); + expectFilter(new Date(2015, 2, 22, 2, 1), 'd.MMMM.yy.H:mm', '22.March.15.2:01'); + }); + + it('should work correctly for `m`', function() { + expectFilter(new Date(2015, 2, 22, 0, 22), 'd.MMMM.yy.m', '22.March.15.22'); + expectFilter(new Date(1991, 2, 8, 0, 59), 'd-MMMM-yyyy-m', '8-March-1991-59'); + expectFilter(new Date(1980, 1, 5, 0, 0), 'MMMM/d/yyyy/m', 'February/5/1980/0'); + expectFilter(new Date(1955, 1, 5, 0, 3), 'yyyy/MMMM/d m', '1955/February/5 3'); + expectFilter(new Date(2013, 7, 11, 0, 46), 'd-MM-yy m', '11-08-13 46'); + expectFilter(new Date(2015, 2, 22, 22, 3), 'd.MMMM.yy.HH:m', '22.March.15.22:3'); + expectFilter(new Date(2015, 2, 22, 2, 1), 'd.MMMM.yy.H:m', '22.March.15.2:1'); + }); + + it('should work correctly for `sss`', function() { + expectFilter(new Date(2015, 2, 22, 0, 0, 0, 123), 'd.MMMM.yy.sss', '22.March.15.123'); + expectFilter(new Date(1991, 2, 8, 0, 0, 0, 59), 'd-MMMM-yyyy-sss', '8-March-1991-059'); + expectFilter(new Date(1980, 1, 5, 0, 0, 0), 'MMMM/d/yyyy/sss', 'February/5/1980/000'); + expectFilter(new Date(1955, 1, 5, 0, 0, 0, 3), 'yyyy/MMMM/d sss', '1955/February/5 003'); + expectFilter(new Date(2013, 7, 11, 0, 0, 0, 46), 'd-MM-yy sss', '11-08-13 046'); + expectFilter(new Date(2015, 2, 22, 22, 33, 0, 44), 'd.MMMM.yy.HH:mm:sss', '22.March.15.22:33:044'); + expectFilter(new Date(2015, 2, 22, 0, 0, 0, 1), 'd.MMMM.yy.H:m:sss', '22.March.15.0:0:001'); + }); + + it('should work correctly for `ss`', function() { + expectFilter(new Date(2015, 2, 22, 0, 0, 22), 'd.MMMM.yy.ss', '22.March.15.22'); + expectFilter(new Date(1991, 2, 8, 0, 0, 59), 'd-MMMM-yyyy-ss', '8-March-1991-59'); + expectFilter(new Date(1980, 1, 5, 0, 0, 0), 'MMMM/d/yyyy/ss', 'February/5/1980/00'); + expectFilter(new Date(1955, 1, 5, 0, 0, 3), 'yyyy/MMMM/d ss', '1955/February/5 03'); + expectFilter(new Date(2013, 7, 11, 0, 0, 46), 'd-MM-yy ss', '11-08-13 46'); + expectFilter(new Date(2015, 2, 22, 22, 33, 44), 'd.MMMM.yy.HH:mm:ss', '22.March.15.22:33:44'); + expectFilter(new Date(2015, 2, 22, 0, 0, 1), 'd.MMMM.yy.H:m:ss', '22.March.15.0:0:01'); + }); + + it('should work correctly for `s`', function() { + expectFilter(new Date(2015, 2, 22, 0, 0, 22), 'd.MMMM.yy.s', '22.March.15.22'); + expectFilter(new Date(1991, 2, 8, 0, 0, 59), 'd-MMMM-yyyy-s', '8-March-1991-59'); + expectFilter(new Date(1980, 1, 5, 0, 0, 0), 'MMMM/d/yyyy/s', 'February/5/1980/0'); + expectFilter(new Date(1955, 1, 5, 0, 0, 3), 'yyyy/MMMM/d s', '1955/February/5 3'); + expectFilter(new Date(2013, 7, 11, 0, 0, 46), 'd-MM-yy s', '11-08-13 46'); + expectFilter(new Date(2015, 2, 22, 22, 33, 4), 'd.MMMM.yy.HH:mm:s', '22.March.15.22:33:4'); + expectFilter(new Date(2015, 2, 22, 22, 3, 4), 'd.MMMM.yy.HH:m:s', '22.March.15.22:3:4'); + }); + + it('should work correctly for `a`', function() { + expectFilter(new Date(2015, 2, 22, 10), 'd.MMMM.yy.hha', '22.March.15.10AM'); + expectFilter(new Date(2015, 2, 22, 22), 'd.MMMM.yy.hha', '22.March.15.10PM'); + expectFilter(new Date(1991, 2, 8, 11), 'd-MMMM-yyyy-hha', '8-March-1991-11AM'); + expectFilter(new Date(1991, 2, 8, 23), 'd-MMMM-yyyy-hha', '8-March-1991-11PM'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/hha', 'February/5/1980/12AM'); + expectFilter(new Date(1980, 1, 5, 12), 'MMMM/d/yyyy/hha', 'February/5/1980/12PM'); + expectFilter(new Date(1955, 1, 5, 3), 'yyyy/MMMM/d hha', '1955/February/5 03AM'); + expectFilter(new Date(1955, 1, 5, 15), 'yyyy/MMMM/d hha', '1955/February/5 03PM'); + expectFilter(new Date(2013, 7, 11, 9), 'd-MM-yy hha', '11-08-13 09AM'); + expectFilter(new Date(2013, 7, 11, 21), 'd-MM-yy hha', '11-08-13 09PM'); + }); + + it('should work correctly for `ww`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'd.MMMM.yy.ww', '17.November.13.47'); + expectFilter(new Date(1991, 2, 8, 0), 'd-MMMM-yyyy-ww', '8-March-1991-10'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/ww', 'February/5/1980/06'); + expectFilter(new Date(1955, 1, 5, 0), 'yyyy/MMMM/d/ww', '1955/February/5/05'); + expectFilter(new Date(2013, 7, 11, 0), 'd-MM-yy ww', '11-08-13 33'); + expectFilter(oldDate, 'yyyy/MM/d ww', '0001/03/6 10'); + }); + + it('should work correctly for `w`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'd.MMMM.yy.w', '17.November.13.47'); + expectFilter(new Date(1991, 2, 8, 0), 'd-MMMM-yyyy-w', '8-March-1991-10'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/w', 'February/5/1980/6'); + expectFilter(new Date(1955, 1, 5, 0), 'yyyy/MMMM/d/w', '1955/February/5/5'); + expectFilter(new Date(2013, 7, 11, 0), 'd-MM-yy w', '11-08-13 33'); + expectFilter(oldDate, 'yyyy/MM/d w', '0001/03/6 10'); + }); + + it('should work correctly for `G`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'd.MMMM.yy.G', '17.November.13.AD'); + expectFilter(new Date(-1991, 2, 8, 0), 'd-MMMM-yyyy-G', '8-March-1991-BC'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/G', 'February/5/1980/AD'); + expectFilter(new Date(-1955, 1, 5, 0), 'yyyy/MMMM/d/G', '1955/February/5/BC'); + expectFilter(new Date(2013, 7, 11, 0), 'd-MM-yy G', '11-08-13 AD'); + }); + + it('should work correctly for `GG`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'd.MMMM.yy.GG', '17.November.13.AD'); + expectFilter(new Date(-1991, 2, 8, 0), 'd-MMMM-yyyy-GG', '8-March-1991-BC'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/GG', 'February/5/1980/AD'); + expectFilter(new Date(-1955, 1, 5, 0), 'yyyy/MMMM/d/GG', '1955/February/5/BC'); + expectFilter(new Date(2013, 7, 11, 0), 'd-MM-yy GG', '11-08-13 AD'); + }); + + it('should work correctly for `GGG`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'd.MMMM.yy.GGG', '17.November.13.AD'); + expectFilter(new Date(-1991, 2, 8, 0), 'd-MMMM-yyyy-GGG', '8-March-1991-BC'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/GGG', 'February/5/1980/AD'); + expectFilter(new Date(-1955, 1, 5, 0), 'yyyy/MMMM/d/GGG', '1955/February/5/BC'); + expectFilter(new Date(2013, 7, 11, 0), 'd-MM-yy GGG', '11-08-13 AD'); + }); + + it('should work correctly for `GGGG`', function() { + expectFilter(new Date(2013, 10, 17, 0), 'd.MMMM.yy.GGGG', '17.November.13.Anno Domini'); + expectFilter(new Date(-1991, 2, 8, 0), 'd-MMMM-yyyy-GGGG', '8-March-1991-Before Christ'); + expectFilter(new Date(1980, 1, 5, 0), 'MMMM/d/yyyy/GGGG', 'February/5/1980/Anno Domini'); + expectFilter(new Date(-1955, 1, 5, 0), 'yyyy/MMMM/d/GGGG', '1955/February/5/Before Christ'); + expectFilter(new Date(2013, 7, 11, 0), 'd-MM-yy GGGG', '11-08-13 Anno Domini'); + }); + }); + describe('with custom formats', function() { it('should work correctly for `dd`, `MM`, `yyyy`', function() { expectParse('17.11.2013', 'dd.MM.yyyy', new Date(2013, 10, 17, 0)); @@ -391,7 +638,6 @@ describe('date parser', function() { expect(dateParser.init).toHaveBeenCalled(); })); - describe('timezone functions', function() { describe('toTimezone', function() { it('adjusts date: PST - EST', function() { diff --git a/src/datepicker/datepicker.js b/src/datepicker/datepicker.js index 549d523fcf..6cd7afcdea 100644 --- a/src/datepicker/datepicker.js +++ b/src/datepicker/datepicker.js @@ -260,7 +260,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst model = dateParser.fromTimezone(model, ngModelOptions.timezone); var dt = { date: date, - label: dateFilter(date, format.replace(/d!/, 'dd')).replace(/M!/, 'MM'), + label: dateParser.filter(date, format), selected: model && this.compare(date, model) === 0, disabled: this.isDisabled(date), current: this.compare(date, new Date()) === 0, @@ -848,11 +848,14 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi scope.date = value; return value; } + scope.date = dateParser.fromTimezone(value, ngModelOptions.timezone); - dateFormat = dateFormat.replace(/M!/, 'MM') - .replace(/d!/, 'dd'); - return dateFilter(scope.date, dateFormat); + if (angular.isNumber(scope.date)) { + scope.date = new Date(scope.date); + } + + return dateParser.filter(scope.date, dateFormat); }); } else { ngModel.$formatters.push(function(value) { @@ -920,7 +923,7 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi if (angular.isDefined(dt)) { scope.date = dt; } - var date = scope.date ? dateFilter(scope.date, dateFormat) : null; // Setting to NULL is necessary for form validators to function + var date = scope.date ? dateParser.filter(scope.date, dateFormat) : null; // Setting to NULL is necessary for form validators to function element.val(date); ngModel.$setViewValue(date);