@@ -187,187 +187,3 @@ exports.ms2DateTime = function(ms, r) {
187
187
}
188
188
return s ;
189
189
} ;
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 = / ( m o n | t u e | w e d | t h u | f r i | s a t | s u n | t h e | o f | s t | n d | r d | t h ) / g,
284
- separatormatch = / [ \s , \/ \- \. \( \) ] + / g,
285
- ampmmatch = / ~ ? ( [ a p ] ) ~ ? m ( ~ | $ ) / ,
286
- replaceampm = function ( m , ap ) { return ap + 'm ' ; } ,
287
- match4Y = / \d \d \d \d / ,
288
- matchMonthName = / ( ^ | ~ ) [ a - z ] { 3 } / ,
289
- matchAMPM = / [ a p ] 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
- } ;
0 commit comments