Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 4b83f6c

Browse files
shahatabtford
authored andcommitted
fix(ngModel): support milliseconds in time and datetime
Closes #8874
1 parent a591e8b commit 4b83f6c

File tree

2 files changed

+51
-23
lines changed

2 files changed

+51
-23
lines changed

src/ng/directive/input.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\
1414
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
1515
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
1616
var DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/;
17-
var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d))?$/;
17+
var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
1818
var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/;
1919
var MONTH_REGEXP = /^(\d{4})-(\d\d)$/;
20-
var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d))?$/;
20+
var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
2121
var DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/;
2222

2323
var $ngModelMinErr = new minErr('ngModel');
@@ -281,8 +281,8 @@ var inputType = {
281281
</example>
282282
*/
283283
'datetime-local': createDateInputType('datetimelocal', DATETIMELOCAL_REGEXP,
284-
createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss']),
285-
'yyyy-MM-ddTHH:mm:ss'),
284+
createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'sss']),
285+
'yyyy-MM-ddTHH:mm:ss.sss'),
286286

287287
/**
288288
* @ngdoc input
@@ -370,8 +370,8 @@ var inputType = {
370370
</example>
371371
*/
372372
'time': createDateInputType('time', TIME_REGEXP,
373-
createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss']),
374-
'HH:mm:ss'),
373+
createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss', 'sss']),
374+
'HH:mm:ss.sss'),
375375

376376
/**
377377
* @ngdoc input
@@ -1067,7 +1067,7 @@ function createDateParser(regexp, mapping) {
10671067
HH: date.getHours(),
10681068
mm: date.getMinutes(),
10691069
ss: date.getSeconds(),
1070-
sss: date.getMilliseconds()
1070+
sss: date.getMilliseconds() / 1000
10711071
};
10721072
} else {
10731073
map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, sss: 0 };
@@ -1078,7 +1078,7 @@ function createDateParser(regexp, mapping) {
10781078
map[mapping[index]] = +part;
10791079
}
10801080
});
1081-
return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss || 0);
1081+
return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss * 1000 || 0);
10821082
}
10831083
}
10841084

test/ng/directive/inputSpec.js

+43-15
Original file line numberDiff line numberDiff line change
@@ -2590,13 +2590,13 @@ describe('input', function() {
25902590
});
25912591

25922592
it('should set the view if the model if a valid Date object.', function(){
2593-
compileInput('<input type="datetime-local" ng-model="tenSecondsToNextYear"/>');
2593+
compileInput('<input type="datetime-local" ng-model="halfSecondToNextYear"/>');
25942594

25952595
scope.$apply(function (){
2596-
scope.tenSecondsToNextYear = new Date(2013, 11, 31, 23, 59, 0);
2596+
scope.halfSecondToNextYear = new Date(2013, 11, 31, 23, 59, 59, 500);
25972597
});
25982598

2599-
expect(inputElm.val()).toBe('2013-12-31T23:59:00');
2599+
expect(inputElm.val()).toBe('2013-12-31T23:59:59.500');
26002600
});
26012601

26022602
it('should set the model undefined if the view is invalid', function (){
@@ -2606,7 +2606,7 @@ describe('input', function() {
26062606
scope.breakMe = new Date(2009, 0, 6, 16, 25, 0);
26072607
});
26082608

2609-
expect(inputElm.val()).toBe('2009-01-06T16:25:00');
2609+
expect(inputElm.val()).toBe('2009-01-06T16:25:00.000');
26102610

26112611
try {
26122612
//set to text for browsers with datetime-local validation.
@@ -2663,7 +2663,21 @@ describe('input', function() {
26632663
scope.$apply(function() {
26642664
scope.value = new Date(Date.UTC(2001, 0, 1, 1, 2, 0));
26652665
});
2666-
expect(inputElm.val()).toBe('2001-01-01T01:02:00');
2666+
expect(inputElm.val()).toBe('2001-01-01T01:02:00.000');
2667+
});
2668+
2669+
it('should allow to specify the milliseconds', function() {
2670+
compileInput('<input type="datetime-local" ng-model="value"" />');
2671+
2672+
changeInputValueTo('2000-01-01T01:02:03.500');
2673+
expect(+scope.value).toBe(+new Date(2000, 0, 1, 1, 2, 3, 500));
2674+
});
2675+
2676+
it('should allow to specify single digit milliseconds', function() {
2677+
compileInput('<input type="datetime-local" ng-model="value"" />');
2678+
2679+
changeInputValueTo('2000-01-01T01:02:03.4');
2680+
expect(+scope.value).toBe(+new Date(2000, 0, 1, 1, 2, 3, 400));
26672681
});
26682682

26692683
it('should allow to specify the seconds', function() {
@@ -2675,7 +2689,7 @@ describe('input', function() {
26752689
scope.$apply(function() {
26762690
scope.value = new Date(2001, 0, 1, 1, 2, 3);
26772691
});
2678-
expect(inputElm.val()).toBe('2001-01-01T01:02:03');
2692+
expect(inputElm.val()).toBe('2001-01-01T01:02:03.000');
26792693
});
26802694

26812695
it('should allow to skip the seconds', function() {
@@ -2854,10 +2868,10 @@ describe('input', function() {
28542868
compileInput('<input type="time" ng-model="threeFortyOnePm"/>');
28552869

28562870
scope.$apply(function (){
2857-
scope.threeFortyOnePm = new Date(1970, 0, 1, 15, 41, 0);
2871+
scope.threeFortyOnePm = new Date(1970, 0, 1, 15, 41, 0, 500);
28582872
});
28592873

2860-
expect(inputElm.val()).toBe('15:41:00');
2874+
expect(inputElm.val()).toBe('15:41:00.500');
28612875
});
28622876

28632877
it('should set the model undefined if the view is invalid', function (){
@@ -2867,7 +2881,7 @@ describe('input', function() {
28672881
scope.breakMe = new Date(1970, 0, 1, 16, 25, 0);
28682882
});
28692883

2870-
expect(inputElm.val()).toBe('16:25:00');
2884+
expect(inputElm.val()).toBe('16:25:00.000');
28712885

28722886
try {
28732887
//set to text for browsers with time validation.
@@ -2924,7 +2938,21 @@ describe('input', function() {
29242938
scope.$apply(function() {
29252939
scope.value = new Date(Date.UTC(1971, 0, 1, 23, 2, 0));
29262940
});
2927-
expect(inputElm.val()).toBe('23:02:00');
2941+
expect(inputElm.val()).toBe('23:02:00.000');
2942+
});
2943+
2944+
it('should allow to specify the milliseconds', function() {
2945+
compileInput('<input type="time" ng-model="value"" />');
2946+
2947+
changeInputValueTo('01:02:03.500');
2948+
expect(+scope.value).toBe(+new Date(1970, 0, 1, 1, 2, 3, 500));
2949+
});
2950+
2951+
it('should allow to specify single digit milliseconds', function() {
2952+
compileInput('<input type="time" ng-model="value"" />');
2953+
2954+
changeInputValueTo('01:02:03.4');
2955+
expect(+scope.value).toBe(+new Date(1970, 0, 1, 1, 2, 3, 400));
29282956
});
29292957

29302958
it('should allow to specify the seconds', function() {
@@ -2936,7 +2964,7 @@ describe('input', function() {
29362964
scope.$apply(function() {
29372965
scope.value = new Date(1970, 0, 1, 1, 2, 3);
29382966
});
2939-
expect(inputElm.val()).toBe('01:02:03');
2967+
expect(inputElm.val()).toBe('01:02:03.000');
29402968
});
29412969

29422970
it('should allow to skip the seconds', function() {
@@ -3192,13 +3220,13 @@ describe('input', function() {
31923220
scope.val = new Date(2013, 1, 2, 3, 4, 5, 6);
31933221
});
31943222

3195-
expect(timeElm.val()).toBe('03:04:05');
3223+
expect(timeElm.val()).toBe('03:04:05.006');
31963224
expect(monthElm.val()).toBe('2013-02');
31973225
expect(weekElm.val()).toBe('2013-W05');
31983226

31993227
changeGivenInputTo(monthElm, '2012-02');
32003228
expect(monthElm.val()).toBe('2012-02');
3201-
expect(timeElm.val()).toBe('03:04:05');
3229+
expect(timeElm.val()).toBe('03:04:05.006');
32023230
expect(weekElm.val()).toBe('2012-W05');
32033231

32043232
changeGivenInputTo(timeElm, '04:05:06');
@@ -3208,10 +3236,10 @@ describe('input', function() {
32083236

32093237
changeGivenInputTo(weekElm, '2014-W01');
32103238
expect(monthElm.val()).toBe('2014-01');
3211-
expect(timeElm.val()).toBe('04:05:06');
3239+
expect(timeElm.val()).toBe('04:05:06.000');
32123240
expect(weekElm.val()).toBe('2014-W01');
32133241

3214-
expect(+scope.val).toBe(+new Date(2014, 0, 2, 4, 5, 6, 6));
3242+
expect(+scope.val).toBe(+new Date(2014, 0, 2, 4, 5, 6, 0));
32153243

32163244
function changeGivenInputTo(inputElm, value) {
32173245
inputElm.val(value);

0 commit comments

Comments
 (0)