Skip to content

Commit 9784b3b

Browse files
committed
axe parseDate - moved to streambed
1 parent 00138aa commit 9784b3b

File tree

3 files changed

+0
-218
lines changed

3 files changed

+0
-218
lines changed

src/lib/dates.js

-184
Original file line numberDiff line numberDiff line change
@@ -187,187 +187,3 @@ exports.ms2DateTime = function(ms, r) {
187187
}
188188
return s;
189189
};
190-
191-
/**
192-
* parseDate: forgiving attempt to turn any date string
193-
* into a javascript date object
194-
*
195-
* first collate all the date formats we want to support, precompiled
196-
* to d3 format objects see below for the string cleaning that happens
197-
* before this separate out 2-digit (y) and 4-digit-year (Y) formats,
198-
* formats with month names (b), and formats with am/pm (I) or no time (D)
199-
* (also includes hour only, as the test is really for a colon) so we can
200-
* cut down the number of tests we need to run for any given string
201-
* (right now all are between 15 and 32 tests)
202-
*/
203-
204-
// TODO: this is way out of date vs. the server-side version
205-
var timeFormats = {
206-
// 24 hour
207-
H: ['%H:%M:%S~%L', '%H:%M:%S', '%H:%M'],
208-
// with am/pm
209-
I: ['%I:%M:%S~%L%p', '%I:%M:%S%p', '%I:%M%p'],
210-
// no colon, ie only date or date with hour (could also support eg 12h34m?)
211-
D: ['%H', '%I%p', '%Hh']
212-
};
213-
214-
var dateFormats = {
215-
Y: [
216-
'%Y~%m~%d',
217-
'%Y%m%d',
218-
'%y%m%d', // YYMMDD, has 6 digits together so will match Y, not y
219-
'%m~%d~%Y', // MM/DD/YYYY has first precedence
220-
'%d~%m~%Y' // then DD/MM/YYYY
221-
],
222-
Yb: [
223-
'%b~%d~%Y', // eg nov 21 2013
224-
'%d~%b~%Y', // eg 21 nov 2013
225-
'%Y~%d~%b', // eg 2013 21 nov (or 2013 q3, after replacement)
226-
'%Y~%b~%d' // eg 2013 nov 21
227-
],
228-
/**
229-
* the two-digit year cases have so many potential ambiguities
230-
* it's not even funny, but we'll try them anyway.
231-
*/
232-
y: [
233-
'%m~%d~%y',
234-
'%d~%m~%y',
235-
'%y~%m~%d'
236-
],
237-
yb: [
238-
'%b~%d~%y',
239-
'%d~%b~%y',
240-
'%y~%d~%b',
241-
'%y~%b~%d'
242-
]
243-
};
244-
245-
// use utc formatter since we're ignoring timezone info
246-
var formatter = d3.time.format.utc;
247-
248-
/**
249-
* ISO8601 and YYYYMMDDHHMMSS are the only ones where date and time
250-
* are not separated by a space, so they get inserted specially here.
251-
* Also a couple formats with no day (so time makes no sense)
252-
*/
253-
var dateTimeFormats = {
254-
Y: {
255-
H: ['%Y~%m~%dT%H:%M:%S', '%Y~%m~%dT%H:%M:%S~%L'].map(formatter),
256-
I: [],
257-
D: ['%Y%m%d%H%M%S', '%Y~%m', '%m~%Y'].map(formatter)
258-
},
259-
Yb: {H: [], I: [], D: ['%Y~%b', '%b~%Y'].map(formatter)},
260-
y: {H: [], I: [], D: []},
261-
yb: {H: [], I: [], D: []}
262-
};
263-
// all others get inserted in all possible combinations from dateFormats and timeFormats
264-
['Y', 'Yb', 'y', 'yb'].forEach(function(dateType) {
265-
dateFormats[dateType].forEach(function(dateFormat) {
266-
// just a date (don't do just a time)
267-
dateTimeFormats[dateType].D.push(formatter(dateFormat));
268-
['H', 'I', 'D'].forEach(function(timeType) {
269-
timeFormats[timeType].forEach(function(timeFormat) {
270-
var a = dateTimeFormats[dateType][timeType];
271-
272-
// 'date time', then 'time date'
273-
a.push(formatter(dateFormat + '~' + timeFormat));
274-
a.push(formatter(timeFormat + '~' + dateFormat));
275-
});
276-
});
277-
});
278-
});
279-
280-
// precompiled regexps for performance
281-
var matchword = /[a-z]*/g,
282-
shortenword = function(m) { return m.substr(0, 3); },
283-
weekdaymatch = /(mon|tue|wed|thu|fri|sat|sun|the|of|st|nd|rd|th)/g,
284-
separatormatch = /[\s,\/\-\.\(\)]+/g,
285-
ampmmatch = /~?([ap])~?m(~|$)/,
286-
replaceampm = function(m, ap) { return ap + 'm '; },
287-
match4Y = /\d\d\d\d/,
288-
matchMonthName = /(^|~)[a-z]{3}/,
289-
matchAMPM = /[ap]m/,
290-
matchcolon = /:/,
291-
matchquarter = /q([1-4])/,
292-
quarters = ['31~mar', '30~jun', '30~sep', '31~dec'],
293-
replacequarter = function(m, n) { return quarters[n - 1]; },
294-
matchTZ = / ?([+\-]\d\d:?\d\d|Z)$/;
295-
296-
function getDateType(v) {
297-
var dateType;
298-
dateType = (match4Y.test(v) ? 'Y' : 'y');
299-
dateType = dateType + (matchMonthName.test(v) ? 'b' : '');
300-
return dateType;
301-
}
302-
303-
function getTimeType(v) {
304-
var timeType;
305-
timeType = matchcolon.test(v) ? (matchAMPM.test(v) ? 'I' : 'H') : 'D';
306-
return timeType;
307-
}
308-
309-
exports.parseDate = function(v) {
310-
// is it already a date? just return it
311-
if(v.getTime) return v;
312-
/**
313-
* otherwise, if it's not a string, return nothing
314-
* the case of numbers that just have years will get
315-
* dealt with elsewhere.
316-
*/
317-
if(typeof v !== 'string') return false;
318-
319-
// first clean up the string a bit to reduce the number of formats we have to test
320-
v = v.toLowerCase()
321-
/**
322-
* cut all words down to 3 characters - this will result in
323-
* some spurious matches, ie whenever the first three characters
324-
* of a word match a month or weekday but that seems more likely
325-
* to fix typos than to make dates where they shouldn't be...
326-
* and then we can omit the long form of months from our testing
327-
*/
328-
.replace(matchword, shortenword)
329-
/**
330-
* remove weekday names, as they get overridden anyway if they're
331-
* inconsistent also removes a few more words
332-
* (ie "tuesday the 26th of november")
333-
* TODO: language support?
334-
* for months too, but these seem to be built into d3
335-
*/
336-
.replace(weekdaymatch, '')
337-
/**
338-
* collapse all separators one ~ at a time, except : which seems
339-
* pretty consistent for the time part use ~ instead of space or
340-
* something since d3 can eat a space as padding on 1-digit numbers
341-
*/
342-
.replace(separatormatch, '~')
343-
// in case of a.m. or p.m. (also take off any space before am/pm)
344-
.replace(ampmmatch, replaceampm)
345-
// turn quarters Q1-4 into dates (quarter ends)
346-
.replace(matchquarter, replacequarter)
347-
.trim()
348-
// also try to ignore timezone info, at least for now
349-
.replace(matchTZ, '');
350-
351-
// now test against the various formats that might match
352-
var out = null,
353-
dateType = getDateType(v),
354-
timeType = getTimeType(v),
355-
formatList,
356-
len;
357-
358-
formatList = dateTimeFormats[dateType][timeType];
359-
len = formatList.length;
360-
361-
for(var i = 0; i < len; i++) {
362-
out = formatList[i].parse(v);
363-
if(out) break;
364-
}
365-
366-
// If not an instance of Date at this point, just return it.
367-
if(!(out instanceof Date)) return false;
368-
// parse() method interprets arguments with local time zone.
369-
var tzoff = out.getTimezoneOffset();
370-
// In general (default) this is not what we want, so force into UTC:
371-
out.setTime(out.getTime() + tzoff * 60 * 1000);
372-
return out;
373-
};

src/lib/index.js

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ var datesModule = require('./dates');
3535
lib.dateTime2ms = datesModule.dateTime2ms;
3636
lib.isDateTime = datesModule.isDateTime;
3737
lib.ms2DateTime = datesModule.ms2DateTime;
38-
lib.parseDate = datesModule.parseDate;
3938
lib.MIN_MS = datesModule.MIN_MS;
4039
lib.MAX_MS = datesModule.MAX_MS;
4140

test/jasmine/tests/lib_test.js

-33
Original file line numberDiff line numberDiff line change
@@ -12,39 +12,6 @@ var Plots = PlotlyInternal.Plots;
1212
describe('Test lib.js:', function() {
1313
'use strict';
1414

15-
describe('parseDate() should', function() {
16-
it('return false on bad (number) input:', function() {
17-
expect(Lib.parseDate(0)).toBe(false);
18-
});
19-
it('return false on bad (string) input:', function() {
20-
expect(Lib.parseDate('toto')).toBe(false);
21-
});
22-
it('work with yyyy-mm-dd string input:', function() {
23-
var input = '2014-12-01',
24-
res = Lib.parseDate(input),
25-
res0 = new Date(2014, 11, 1);
26-
expect(res.getTime()).toEqual(res0.getTime());
27-
});
28-
it('work with mm/dd/yyyy string input:', function() {
29-
var input = '12/01/2014',
30-
res = Lib.parseDate(input),
31-
res0 = new Date(2014, 11, 1);
32-
expect(res.getTime()).toEqual(res0.getTime());
33-
});
34-
it('work with yyyy-mm-dd HH:MM:SS.sss string input:', function() {
35-
var input = '2014-12-01 09:50:05.124',
36-
res = Lib.parseDate(input),
37-
res0 = new Date(2014, 11, 1, 9, 50, 5, 124);
38-
expect(res.getTime()).toEqual(res0.getTime());
39-
});
40-
it('work with mm/dd/yyyy HH:MM:SS string input:', function() {
41-
var input = '2014-12-01 09:50:05',
42-
res = Lib.parseDate(input),
43-
res0 = new Date(2014, 11, 1, 9, 50, 5);
44-
expect(res.getTime()).toEqual(res0.getTime());
45-
});
46-
});
47-
4815
describe('interp() should', function() {
4916
it('return 1.75 as Q1 of [1, 2, 3, 4, 5]:', function() {
5017
var input = [1, 2, 3, 4, 5],

0 commit comments

Comments
 (0)