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

Commit 64bc907

Browse files
committed
Merge pull request #11 from dnasir/dev
Merge dev > master
2 parents 1c2d26e + 3903145 commit 64bc907

File tree

3 files changed

+120
-48
lines changed

3 files changed

+120
-48
lines changed

dateparser.js

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Angular DateParser 1.0.5
2+
* Angular DateParser 1.0.7
33
* https://github.com/dnasir/angular-dateParser
44
*
55
* Copyright 2013, Dzulqarnain Nasir
@@ -11,13 +11,16 @@
1111

1212
angular.module('dateParser', [])
1313
.factory('dateParserHelpers', [function() {
14+
15+
'use strict';
16+
1417
return {
1518

1619
// Returns true if string contains only integers
17-
isJustNumbers: function(string) {
20+
hasOnlyIntegers: function(string) {
1821
if(!string) return false;
1922

20-
var digits = "1234567890";
23+
var digits = '1234567890';
2124

2225
for (var i = 0; i < string.length; i++) {
2326
if (digits.indexOf(string.charAt(i)) == -1) return false;
@@ -31,7 +34,7 @@ angular.module('dateParser', [])
3134
for (var i = maxLength; i >= minLength; i--) {
3235
var extracted = string.substring(startPoint, startPoint + i);
3336

34-
if(this.isJustNumbers(extracted)) {
37+
if(this.hasOnlyIntegers(extracted)) {
3538
return extracted;
3639
}
3740
}
@@ -41,6 +44,8 @@ angular.module('dateParser', [])
4144
}])
4245
.factory('$dateParser', ['$locale', 'dateParserHelpers', function($locale, dateParserHelpers) {
4346

47+
'use strict';
48+
4449
// Fetch date and time formats from $locale service
4550
var datetimeFormats = $locale.DATETIME_FORMATS;
4651

@@ -79,8 +84,8 @@ angular.module('dateParser', [])
7984
hh = 0,
8085
mm = 0,
8186
ss = 0,
87+
sss = 0,
8288
ampm = 'am',
83-
now = new Date(),
8489
z = 0,
8590
parsedZ = false;
8691

@@ -115,7 +120,6 @@ angular.module('dateParser', [])
115120
}
116121

117122
// Extract contents of value based on format token
118-
// TODO: Implement millisecond (.sss or ,sss) extractor
119123
if (token == 'yyyy' || token == 'yy' || token == 'y') {
120124
var minLength, maxLength;
121125

@@ -227,6 +231,14 @@ angular.module('dateParser', [])
227231
}
228232

229233
i_val += ss.length;
234+
} else if (token === 'sss') {
235+
sss = dateParserHelpers.getInteger(val, i_val, 3, 3);
236+
237+
if (sss === null || (sss < 0) || (sss > 999)) {
238+
throw 'Invalid milliseconds';
239+
}
240+
241+
i_val += 3;
230242
} else if (token == 'a') {
231243
if (val.substring(i_val, i_val + 2).toLowerCase() == 'am') {
232244
ampm = 'AM';
@@ -269,6 +281,7 @@ angular.module('dateParser', [])
269281
hh = parseInt(hh);
270282
mm = parseInt(mm);
271283
ss = parseInt(ss);
284+
sss = parseInt(sss);
272285

273286
// Is date valid for month?
274287
if (month == 2) {
@@ -297,15 +310,15 @@ angular.module('dateParser', [])
297310
hh -= 12;
298311
}
299312

300-
var localDate = new Date(year, month - 1, date, hh, mm, ss);
313+
var localDate = new Date(year, month - 1, date, hh, mm, ss, sss);
314+
301315
if (parsedZ) {
302-
return new Date(localDate.getTime() + (z + localDate.getTimezoneOffset()) * 60 * 1000);
303-
} else {
304-
return localDate;
316+
return new Date(localDate.getTime() - (z + localDate.getTimezoneOffset()) * 60000);
305317
}
318+
319+
return localDate;
306320
} catch(e) {
307-
// TODO: Return undefined?
308-
return new Date(undefined);
321+
return undefined;
309322
}
310323
};
311324
}]);

demo.html

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,37 +39,48 @@
3939
border-radius: 4px 0 4px 0;
4040
}
4141

42-
.dn-timepicker-popup {
43-
max-height: 300px;
44-
overflow-y: scroll;
45-
}
42+
.footer {
43+
text-align: center;
44+
padding: 30px 0;
45+
margin-top: 70px;
46+
border-top: 1px solid #e5e5e5;
47+
background-color: #f5f5f5;
48+
}
49+
50+
.footer p {
51+
margin-bottom: 0;
52+
}
4653
</style>
4754
</head>
4855
<body>
4956
<div class="container" ng-controller="controller">
5057
<header class="page-header">
51-
<h1>Angular DateParser <small>Demo</small></h1>
58+
<h1>AngularJS DateParser <small>Demo</small></h1>
5259
</header>
5360

54-
<p>This parser converts date and time strings into JavaScript Date objects.</p>
61+
<p>The AngularJS library has a <a href="http://docs.angularjs.org/api/ng/filter/date" target="_blank" title="AngularJS date filter">date filter</a> that allows JavaScript Date objects to be displayed using a provided format. This is an awesome feature, and it's great that you can use it anywhere, including text input boxes. But the problem is that it only works one-way. There's currently no way to convert strings back into Date objects while using the same format initially used to display it. This parser was designed to overcome this problem.</p>
5562

5663
<h4>Basic</h4>
64+
<p>This is a basic example demonstrating how the parser can convert manually entered date strings into JavaScript Date objects.</p>
65+
5766
<div class="bs-docs-example">
5867
<p>
5968
<div class="input-prepend">
6069
<span class="add-on">Date and time</span>
6170
<input type="text" ng-model="date" date-parser="dd.MM.yyyy HH:mm" />
6271
</div>
6372
</p>
64-
<p>Selected date: {{date | date:'MMM d, y h:m'}}</p>
73+
<p>Selected date: {{date | date:'MMM d, y h:mm'}}</p>
6574
</div>
75+
6676
<h6>Code</h6>
6777
<div>
6878
<pre class="brush: html">&lt;input type="text" ng-model="date" date-parser="dd.MM.yyyy HH:mm" /&gt;</pre>
6979
</div>
7080

7181
<h4>Using Angular Date Formats</h4>
72-
<p>Use all the shortname formats provided by Angular.</p>
82+
<p>The AngularJS date filter comes with several shortname formats that you can use. The DateParser can recognise these formats and will convert the date strings accordingly.</p>
83+
7384
<div class="bs-docs-example">
7485
<p>
7586
<div class="input-prepend">
@@ -122,8 +133,9 @@ <h4>Using Angular Date Formats</h4>
122133
<input type="text" ng-model="date" date-parser="shortTime" />
123134
</div>
124135
</p>
125-
<p>Selected date: {{date | date:'MMM d, y h:m'}}</p>
136+
<p>Selected date: {{date | date:'MMM d, y h:mm'}}</p>
126137
</div>
138+
127139
<h6>Code</h6>
128140
<div>
129141
<pre class="brush: html">&lt;input type="text" ng-model="date" date-parser="medium" /&gt;
@@ -138,7 +150,8 @@ <h6>Code</h6>
138150
</div>
139151

140152
<h4>Dynamic Formats</h4>
141-
<p>Format can be dynamically changed and the view will automatically update to use the new format.</p>
153+
<p>Date string formats can be changed on-the-fly and associated views will automatically be updated to use the new format.</p>
154+
142155
<div class="bs-docs-example">
143156
<div class="input-prepend">
144157
<span class="add-on">Format</span>
@@ -148,21 +161,47 @@ <h4>Dynamic Formats</h4>
148161
<span class="add-on">Date</span>
149162
<input type="text" ng-model="date" date-parser="{{format}}" />
150163
</div>
151-
<p>Selected date: {{date | date:'MMM d, y h:m'}}</p>
164+
<p>Selected date: {{date | date:'MMM d, y h:mm'}}</p>
152165
</div>
166+
153167
<h6>Code</h6>
154168
<div ng-non-bindable>
155169
<pre class="brush: html" ng->&lt;input type="text" ng-model="date" date-parser="{{format}}" /&gt;</pre>
170+
</div>
171+
172+
<h4>Timezones</h4>
173+
<p>The parser also allows you to change the timezone. However, bear in mind that the model will still contain the date and time for the local timezone, minus the offset.</p>
174+
175+
<div class="bs-docs-example">
176+
<div class="input-prepend">
177+
<span class="add-on">Date</span>
178+
<input type="text" ng-model="date" date-parser="dd/MM/yyyy HH:mm Z" />
179+
</div>
180+
<p>Selected date: {{date | date:'MMM d, y h:mm Z'}}</p>
181+
</div>
182+
183+
<h6>Code</h6>
184+
<div ng-non-bindable>
185+
<pre class="brush: html" ng->&lt;input type="text" ng-model="date" date-parser="dd/MM/yyyy HH:mm Z" /&gt;</pre>
156186
</div>
157187
</div>
158188

159-
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
189+
<footer class="footer">
190+
<div class="container">
191+
<p>Copyright &copy; 2014 <a href="http://dnasir.com" title="Dzulqarnain Nasir">Dzulqarnain Nasir</a></p>
192+
<p>Code licensed under <a href="http://opensource.org/licenses/MIT" target="_blank" title="The MIT License">MIT License</a></p>
193+
</div>
194+
</footer>
195+
196+
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
160197
<script src="dateparser.js"></script>
161198
<script src="dateparser.directive.js"></script>
162199
<script>
163200
function controller($scope) {
164201
$scope.format = 'dd.MM.yyyy';
165202
$scope.date = new Date();
203+
204+
166205
}
167206
</script>
168207

test/dateparser.spec.js

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ describe('dateParser', function() {
44

55
describe('helper function test', function() {
66
it('should return true if value given is an integer', inject(function(dateParserHelpers) {
7-
expect(dateParserHelpers.isJustNumbers('123')).toBe(true);
8-
expect(dateParserHelpers.isJustNumbers('123.5')).toBe(false);
9-
expect(dateParserHelpers.isJustNumbers('abc')).toBe(false);
10-
expect(dateParserHelpers.isJustNumbers('12:')).toBe(false);
11-
expect(dateParserHelpers.isJustNumbers('012')).toBe(true);
12-
expect(dateParserHelpers.isJustNumbers('0:12')).toBe(false);
13-
expect(dateParserHelpers.isJustNumbers(null)).toBe(false);
14-
expect(dateParserHelpers.isJustNumbers(undefined)).toBe(false);
7+
expect(dateParserHelpers.hasOnlyIntegers('123')).toBe(true);
8+
expect(dateParserHelpers.hasOnlyIntegers('123.5')).toBe(false);
9+
expect(dateParserHelpers.hasOnlyIntegers('abc')).toBe(false);
10+
expect(dateParserHelpers.hasOnlyIntegers('12:')).toBe(false);
11+
expect(dateParserHelpers.hasOnlyIntegers('012')).toBe(true);
12+
expect(dateParserHelpers.hasOnlyIntegers('0:12')).toBe(false);
13+
expect(dateParserHelpers.hasOnlyIntegers(null)).toBe(false);
14+
expect(dateParserHelpers.hasOnlyIntegers(undefined)).toBe(false);
1515
}));
1616

1717
it('should return integers extracted from a string', inject(function(dateParserHelpers) {
@@ -28,16 +28,24 @@ describe('dateParser', function() {
2828
var str1 = '17.12.2013',
2929
str2 = '17-12-2013 12:59',
3030
str3 = 'December 17, 2013 12:59',
31-
str4 = '4:15 in the morning';
31+
str4 = '4:15 in the morning',
32+
str5 = '4/3/2014 10:45:45.345',
33+
str6 = 'November 8, 1983 9:55pm',
34+
str7 = '2011-04-01';
3235

3336
var format1 = 'dd.MM.yyyy',
3437
format2 = 'dd-MM-yyyy HH:mm',
3538
format3 = 'MMMM d, yyyy HH:mm',
36-
format4 = "h:m 'in the morning'";
39+
format4 = "h:m 'in the morning'",
40+
format5 = 'd/M/yyyy H:mm:ss.sss',
41+
format6 = 'MMMM d, yyyy h:mma',
42+
format7 = 'yy-MMMM-dd';
3743

3844
var expected1 = new Date(2013, 11, 17, 0, 0, 0),
3945
expected2 = new Date(2013, 11, 17, 12, 59, 0),
40-
expected3 = new Date(2013, 11, 17, 12, 59, 0);
46+
expected3 = new Date(2013, 11, 17, 12, 59, 0),
47+
expected5 = new Date(2014, 2, 4, 10, 45, 45, 345),
48+
expected6 = new Date(1983, 10, 8, 21, 55, 0);
4149

4250
expect($dateParser(str1, format1).getTime()).toBe(expected1.getTime());
4351
expect($dateParser(str2, format2).getTime()).toBe(expected2.getTime());
@@ -46,34 +54,46 @@ describe('dateParser', function() {
4654
var result4 = $dateParser(str4, format4);
4755
expect(result4.getHours()).toBe(4);
4856
expect(result4.getMinutes()).toBe(15);
57+
58+
expect($dateParser(str5, format5).getTime()).toBe(expected5.getTime());
59+
expect($dateParser(str6, format6).getTime()).toBe(expected6.getTime());
60+
expect($dateParser(str7, format7)).toBe(undefined);
4961
}));
5062

5163
it('should properly parse timezones', inject(function($dateParser) {
5264
var str1 = 'December 17, 2013 12:59 +0300',
53-
str2 = 'December 17, 2013 12:59 -0300';
65+
str2 = 'April 17, 2013 12:59 -0300',
66+
str3 = 'December 17, 2013 12:59 +1300',
67+
str4 = 'January 1, 2020 23:59 +1200',
68+
str5 = 'July 1, 2020 23:59 -0700',
69+
str6 = 'November 8, 1983 09:59 +0530';
5470

5571
var format = 'MMMM d, yyyy HH:mm Z';
5672

57-
var expectedBase = new Date(2013, 11, 17, 12, 59, 0),
58-
expected1 = new Date(expectedBase.getTime() + (180 + expectedBase.getTimezoneOffset()) * 60 * 1000),
59-
expected2 = new Date(expectedBase.getTime() + (-180 + expectedBase.getTimezoneOffset()) * 60 * 1000);
60-
61-
expect($dateParser(str1, format).getTime()).toBe(expected1.getTime());
62-
expect($dateParser(str2, format).getTime()).toBe(expected2.getTime());
73+
expect($dateParser(str1, format).getUTCHours()).toBe(9);
74+
expect($dateParser(str2, format).getUTCHours()).toBe(15);
75+
expect($dateParser(str3, format)).toBe(undefined);
76+
expect($dateParser(str4, format).getUTCHours()).toBe(11);
77+
expect($dateParser(str5, format).getUTCHours()).toBe(6);
78+
expect($dateParser(str6, format).getUTCHours()).toBe(4);
79+
expect($dateParser(str6, format).getUTCMinutes()).toBe(29);
6380
}));
6481

65-
it('should return Invalid Date for invalid date strings', inject(function($dateParser) {
82+
it('should return undefined for invalid date strings and pattern mismatches', inject(function($dateParser) {
6683
var str1 = '29.02.2013',
6784
str2 = '31-04-2013',
68-
str3 = 'November 31, 2013';
85+
str3 = 'November 31, 2013',
86+
str4 = '12/12/2012';
6987

7088
var format1 = 'dd.MM.yyyy',
7189
format2 = 'dd-MM-yyyy',
72-
format3 = 'MMMM d, yyyy';
90+
format3 = 'MMMM d, yyyy',
91+
format4 = 'dd/MMMM/yy';
7392

74-
expect(isNaN($dateParser(str1, format1))).toBe(true);
75-
expect(isNaN($dateParser(str2, format2))).toBe(true);
76-
expect(isNaN($dateParser(str3, format3))).toBe(true);
93+
expect($dateParser(str1, format1)).toBe(undefined);
94+
expect($dateParser(str2, format2)).toBe(undefined);
95+
expect($dateParser(str3, format3)).toBe(undefined);
96+
expect($dateParser(str4, format4)).toBe(undefined);
7797
}));
7898
});
7999

0 commit comments

Comments
 (0)