@@ -233,112 +233,28 @@ $.extend(Timepicker.prototype, {
233
233
// parse the time string from input value or _setTime
234
234
//########################################################################
235
235
_parseTime : function ( timeString , withDate ) {
236
- var regstr = this . _defaults . timeFormat . toString ( )
237
- . replace ( / h { 1 , 2 } / ig, '(\\d?\\d)' )
238
- . replace ( / m { 1 , 2 } / ig, '(\\d?\\d)' )
239
- . replace ( / s { 1 , 2 } / ig, '(\\d?\\d)' )
240
- . replace ( / l { 1 } / ig, '(\\d?\\d?\\d)' )
241
- . replace ( / t { 1 , 2 } / ig, this . _getPatternAmpm ( ) )
242
- . replace ( / z { 1 } / ig, '(z|[-+]\\d\\d:?\\d\\d)?' )
243
- . replace ( / \s / g, '\\s?' ) + this . _defaults . timeSuffix + '$' ,
244
- order = this . _getFormatPositions ( ) ,
245
- ampm = '' ,
246
- treg ;
247
-
248
- if ( ! this . inst ) this . inst = $ . datepicker . _getInst ( this . $input [ 0 ] ) ;
249
-
250
- if ( withDate || ! this . _defaults . timeOnly ) {
251
- // the time should come after x number of characters and a space.
252
- // x = at least the length of text specified by the date format
236
+ if ( withDate || ! this . _defaults . timeOnly )
237
+ {
238
+ if ( ! this . inst ) this . inst = $ . datepicker . _getInst ( this . $input [ 0 ] ) ;
253
239
var dp_dateFormat = $ . datepicker . _get ( this . inst , 'dateFormat' ) ;
254
- // escape special regex characters in the seperator
255
- var specials = new RegExp ( "[.*+?|()\\[\\]{}\\\\]" , "g" ) ;
256
- regstr = '^.{' + dp_dateFormat . length + ',}?' + this . _defaults . separator . replace ( specials , "\\$&" ) + regstr ;
257
- }
258
-
259
- treg = timeString . match ( new RegExp ( regstr , 'i' ) ) ;
260
-
261
- if ( treg ) {
262
- if ( order . t !== - 1 ) {
263
- if ( treg [ order . t ] === undefined || treg [ order . t ] . length === 0 ) {
264
- ampm = '' ;
265
- this . ampm = '' ;
266
- } else {
267
- ampm = $ . inArray ( treg [ order . t ] . toUpperCase ( ) , this . amNames ) !== - 1 ? 'AM' : 'PM' ;
268
- this . ampm = this . _defaults [ ampm == 'AM' ? 'amNames' : 'pmNames' ] [ 0 ] ;
269
- }
270
- }
271
-
272
- if ( order . h !== - 1 ) {
273
- if ( ampm == 'AM' && treg [ order . h ] == '12' )
274
- this . hour = 0 ; // 12am = 0 hour
275
- else if ( ampm == 'PM' && treg [ order . h ] != '12' )
276
- this . hour = ( parseFloat ( treg [ order . h ] ) + 12 ) . toFixed ( 0 ) ; // 12pm = 12 hour, any other pm = hour + 12
277
- else this . hour = Number ( treg [ order . h ] ) ;
278
- }
279
-
280
- if ( order . m !== - 1 ) this . minute = Number ( treg [ order . m ] ) ;
281
- if ( order . s !== - 1 ) this . second = Number ( treg [ order . s ] ) ;
282
- if ( order . l !== - 1 ) this . millisec = Number ( treg [ order . l ] ) ;
283
- if ( order . z !== - 1 && treg [ order . z ] !== undefined ) {
284
- var tz = treg [ order . z ] . toUpperCase ( ) ;
285
- switch ( tz . length ) {
286
- case 1 : // Z
287
- tz = this . _defaults . timezoneIso8601 ? 'Z' : '+0000' ;
288
- break ;
289
- case 5 : // +hhmm
290
- if ( this . _defaults . timezoneIso8601 )
291
- tz = tz . substring ( 1 ) == '0000'
292
- ? 'Z'
293
- : tz . substring ( 0 , 3 ) + ':' + tz . substring ( 3 ) ;
294
- break ;
295
- case 6 : // +hh:mm
296
- if ( ! this . _defaults . timezoneIso8601 )
297
- tz = tz == 'Z' || tz . substring ( 1 ) == '00:00'
298
- ? '+0000'
299
- : tz . replace ( / : / , '' ) ;
300
- else if ( tz . substring ( 1 ) == '00:00' )
301
- tz = 'Z' ;
302
- break ;
303
- }
304
- this . timezone = tz ;
305
- }
306
-
307
- return true ;
308
-
309
- }
310
- return false ;
311
- } ,
312
-
313
- //########################################################################
314
- // pattern for standard and localized AM/PM markers
315
- //########################################################################
316
- _getPatternAmpm : function ( ) {
317
- var markers = [ ] ,
318
- o = this . _defaults ;
319
- if ( o . amNames )
320
- $ . merge ( markers , o . amNames ) ;
321
- if ( o . pmNames )
322
- $ . merge ( markers , o . pmNames ) ;
323
- markers = $ . map ( markers , function ( val ) { return val . replace ( / [ . * + ? | ( ) \[ \] { } \\ ] / g, '\\$&' ) ; } ) ;
324
- return '(' + markers . join ( '|' ) + ')?' ;
325
- } ,
326
-
327
- //########################################################################
328
- // figure out position of time elements.. cause js cant do named captures
329
- //########################################################################
330
- _getFormatPositions : function ( ) {
331
- var finds = this . _defaults . timeFormat . toLowerCase ( ) . match ( / ( h { 1 , 2 } | m { 1 , 2 } | s { 1 , 2 } | l { 1 } | t { 1 , 2 } | z ) / g) ,
332
- orders = { h : - 1 , m : - 1 , s : - 1 , l : - 1 , t : - 1 , z : - 1 } ;
333
-
334
- if ( finds )
335
- for ( var i = 0 ; i < finds . length ; i ++ )
336
- if ( orders [ finds [ i ] . toString ( ) . charAt ( 0 ) ] == - 1 )
337
- orders [ finds [ i ] . toString ( ) . charAt ( 0 ) ] = i + 1 ;
338
-
339
- return orders ;
240
+ try {
241
+ var parseRes = parseDateTimeInternal ( dp_dateFormat , this . _defaults . timeFormat , timeString , $ . datepicker . _getFormatConfig ( this . inst ) , this . _defaults ) ;
242
+ if ( ! parseRes . timeObj ) return false ;
243
+ $ . extend ( this , parseRes . timeObj ) ;
244
+ } catch ( err )
245
+ {
246
+ return false ;
247
+ }
248
+ return true ;
249
+ }
250
+ else
251
+ {
252
+ var timeObj = $ . datepicker . parseTime ( this . _defaults . timeFormat , timeString , this . _defaults ) ;
253
+ $ . extend ( this , parseRes . timeObj ) ;
254
+ return true ;
255
+ }
340
256
} ,
341
-
257
+
342
258
//########################################################################
343
259
// generate and inject html for timepicker into ui datepicker
344
260
//########################################################################
@@ -934,6 +850,117 @@ $.fn.extend({
934
850
}
935
851
} ) ;
936
852
853
+ $ . datepicker . parseDateTime = function ( dateFormat , timeFormat , dateTimeString , dateSettings , timeSettings ) {
854
+ var parseRes = parseDateTimeInternal ( dateFormat , timeFormat , dateTimeString , dateSettings , timeSettings ) ;
855
+ if ( parseRes . timeObj )
856
+ {
857
+ var t = parseRes . timeObj ;
858
+ parseRes . date . setHours ( t . hour , t . minute , t . second , t . millisec ) ;
859
+ }
860
+
861
+ return parseRes . date ;
862
+ }
863
+
864
+ $ . datepicker . parseTime = function ( timeFormat , timeString , options ) {
865
+
866
+ //########################################################################
867
+ // pattern for standard and localized AM/PM markers
868
+ //########################################################################
869
+ var getPatternAmpm = function ( amNames , pmNames ) {
870
+ var markers = [ ] ;
871
+ if ( amNames )
872
+ $ . merge ( markers , amNames ) ;
873
+ if ( pmNames )
874
+ $ . merge ( markers , pmNames ) ;
875
+ markers = $ . map ( markers , function ( val ) { return val . replace ( / [ . * + ? | ( ) \[ \] { } \\ ] / g, '\\$&' ) ; } ) ;
876
+ return '(' + markers . join ( '|' ) + ')?' ;
877
+ }
878
+
879
+ //########################################################################
880
+ // figure out position of time elements.. cause js cant do named captures
881
+ //########################################################################
882
+ var getFormatPositions = function ( timeFormat ) {
883
+ var finds = timeFormat . toLowerCase ( ) . match ( / ( h { 1 , 2 } | m { 1 , 2 } | s { 1 , 2 } | l { 1 } | t { 1 , 2 } | z ) / g) ,
884
+ orders = { h : - 1 , m : - 1 , s : - 1 , l : - 1 , t : - 1 , z : - 1 } ;
885
+
886
+ if ( finds )
887
+ for ( var i = 0 ; i < finds . length ; i ++ )
888
+ if ( orders [ finds [ i ] . toString ( ) . charAt ( 0 ) ] == - 1 )
889
+ orders [ finds [ i ] . toString ( ) . charAt ( 0 ) ] = i + 1 ;
890
+
891
+ return orders ;
892
+ }
893
+
894
+ var o = extendRemove ( extendRemove ( { } , $ . timepicker . _defaults ) , options || { } ) ;
895
+
896
+ var regstr = '^' + timeFormat . toString ( )
897
+ . replace ( / h { 1 , 2 } / ig, '(\\d?\\d)' )
898
+ . replace ( / m { 1 , 2 } / ig, '(\\d?\\d)' )
899
+ . replace ( / s { 1 , 2 } / ig, '(\\d?\\d)' )
900
+ . replace ( / l { 1 } / ig, '(\\d?\\d?\\d)' )
901
+ . replace ( / t { 1 , 2 } / ig, getPatternAmpm ( o . amNames , o . pmNames ) )
902
+ . replace ( / z { 1 } / ig, '(z|[-+]\\d\\d:?\\d\\d)?' )
903
+ . replace ( / \s / g, '\\s?' ) + o . timeSuffix + '$' ,
904
+ order = getFormatPositions ( timeFormat ) ,
905
+ ampm = '' ,
906
+ treg ;
907
+
908
+ treg = timeString . match ( new RegExp ( regstr , 'i' ) ) ;
909
+
910
+ var resTime = { hour : 0 , minute : 0 , second : 0 , millisec : 0 } ;
911
+
912
+ if ( treg ) {
913
+ if ( order . t !== - 1 ) {
914
+ if ( treg [ order . t ] === undefined || treg [ order . t ] . length === 0 ) {
915
+ ampm = '' ;
916
+ resTime . ampm = '' ;
917
+ } else {
918
+ ampm = $ . inArray ( treg [ order . t ] , o . amNames ) !== - 1 ? 'AM' : 'PM' ;
919
+ resTime . ampm = o [ ampm == 'AM' ? 'amNames' : 'pmNames' ] [ 0 ] ;
920
+ }
921
+ }
922
+
923
+ if ( order . h !== - 1 ) {
924
+ if ( ampm == 'AM' && treg [ order . h ] == '12' )
925
+ resTime . hour = 0 ; // 12am = 0 hour
926
+ else if ( ampm == 'PM' && treg [ order . h ] != '12' )
927
+ resTime . hour = parseInt ( treg [ order . h ] , 10 ) + 12 ; // 12pm = 12 hour, any other pm = hour + 12
928
+ else resTime . hour = Number ( treg [ order . h ] ) ;
929
+ }
930
+
931
+ if ( order . m !== - 1 ) resTime . minute = Number ( treg [ order . m ] ) ;
932
+ if ( order . s !== - 1 ) resTime . second = Number ( treg [ order . s ] ) ;
933
+ if ( order . l !== - 1 ) resTime . millisec = Number ( treg [ order . l ] ) ;
934
+ if ( order . z !== - 1 && treg [ order . z ] !== undefined ) {
935
+ var tz = treg [ order . z ] . toUpperCase ( ) ;
936
+ switch ( tz . length ) {
937
+ case 1 : // Z
938
+ tz = o . timezoneIso8601 ? 'Z' : '+0000' ;
939
+ break ;
940
+ case 5 : // +hhmm
941
+ if ( o . timezoneIso8601 )
942
+ tz = tz . substring ( 1 ) == '0000'
943
+ ? 'Z'
944
+ : tz . substring ( 0 , 3 ) + ':' + tz . substring ( 3 ) ;
945
+ break ;
946
+ case 6 : // +hh:mm
947
+ if ( ! o . timezoneIso8601 )
948
+ tz = tz == 'Z' || tz . substring ( 1 ) == '00:00'
949
+ ? '+0000'
950
+ : tz . replace ( / : / , '' ) ;
951
+ else if ( tz . substring ( 1 ) == '00:00' )
952
+ tz = 'Z' ;
953
+ break ;
954
+ }
955
+ resTime . timezone = tz ;
956
+ }
957
+
958
+ return resTime ;
959
+
960
+ }
961
+ return null ;
962
+ } ,
963
+
937
964
//########################################################################
938
965
// format the time all pretty...
939
966
// format = string format of the time
@@ -1240,21 +1267,8 @@ $.datepicker._getDateDatepicker = function(target, noDefault) {
1240
1267
//#######################################################################################
1241
1268
$ . datepicker . _base_parseDate = $ . datepicker . parseDate ;
1242
1269
$ . datepicker . parseDate = function ( format , value , settings ) {
1243
- var date ;
1244
- try {
1245
- date = this . _base_parseDate ( format , value , settings ) ;
1246
- } catch ( err ) {
1247
- if ( err . indexOf ( ":" ) >= 0 ) {
1248
- // Hack! The error message ends with a colon, a space, and
1249
- // the "extra" characters. We rely on that instead of
1250
- // attempting to perfectly reproduce the parsing algorithm.
1251
- date = this . _base_parseDate ( format , value . substring ( 0 , value . length - ( err . length - err . indexOf ( ':' ) - 2 ) ) , settings ) ;
1252
- } else {
1253
- // The underlying error was not related to the time
1254
- throw err ;
1255
- }
1256
- }
1257
- return date ;
1270
+ var splitRes = splitDateTime ( dateFormat , dateTimeString , dateSettings ) ;
1271
+ return $ . datepicker . _base_parseDate ( dateFormat , splitRes [ 0 ] , dateSettings ) ;
1258
1272
} ;
1259
1273
1260
1274
//#######################################################################################
@@ -1332,7 +1346,60 @@ function extendRemove(target, props) {
1332
1346
return target ;
1333
1347
} ;
1334
1348
1349
+ //#######################################################################################
1350
+ // Splits datetime string into date ans time substrings.
1351
+ // Throws exception when date can't be parsed
1352
+ // If only date is present, time substring eill be ''
1353
+ //#######################################################################################
1354
+ var splitDateTime = function ( dateFormat , dateTimeString , dateSettings )
1355
+ {
1356
+ try {
1357
+ var date = $ . datepicker . _base_parseDate ( dateFormat , dateTimeString , dateSettings ) ;
1358
+ } catch ( err ) {
1359
+ if ( err . indexOf ( ":" ) >= 0 ) {
1360
+ // Hack! The error message ends with a colon, a space, and
1361
+ // the "extra" characters. We rely on that instead of
1362
+ // attempting to perfectly reproduce the parsing algorithm.
1363
+ var dateStringLength = dateTimeString . length - ( err . length - err . indexOf ( ':' ) - 2 ) ;
1364
+ var timeString = dateTimeString . substring ( dateStringLength ) ;
1365
+
1366
+ return [ dateTimeString . substring ( 0 , dateStringLength ) , dateTimeString . substring ( dateStringLength ) ]
1367
+
1368
+ } else {
1369
+ throw err ;
1370
+ }
1371
+ }
1372
+ return [ dateTimeString , '' ] ;
1373
+ }
1374
+
1375
+ //#######################################################################################
1376
+ // Internal function to parse datetime interval
1377
+ // Returns: {date: Date, timeObj: Object}, where
1378
+ // date - parsed date without time (type Date)
1379
+ // timeObj = {hour: , minute: , second: , millisec: } - parsed time. Optional
1380
+ //#######################################################################################
1381
+ var parseDateTimeInternal = function ( dateFormat , timeFormat , dateTimeString , dateSettings , timeSettings )
1382
+ {
1383
+ var date ;
1384
+ var splitRes = splitDateTime ( dateFormat , dateTimeString , dateSettings ) ;
1385
+ date = $ . datepicker . _base_parseDate ( dateFormat , splitRes [ 0 ] , dateSettings ) ;
1386
+ if ( splitRes [ 1 ] != '' )
1387
+ {
1388
+ var timeString = splitRes [ 1 ] ;
1389
+ var separator = timeSettings && timeSettings . separator ? timeSettings . separator : $ . timepicker . _defaults . separator ;
1390
+ if ( timeString . indexOf ( separator ) != 0 )
1391
+ throw 'Missing time separator' ;
1392
+ timeString = timeString . substring ( separator . length ) ;
1393
+ var parsedTime = $ . datepicker . parseTime ( timeFormat , timeString , timeSettings ) ;
1394
+ if ( parsedTime === null )
1395
+ throw 'Wrong time format' ;
1396
+ return { date : date , timeObj : parsedTime } ;
1397
+ }
1398
+ else
1399
+ return { date : date } ;
1400
+ }
1401
+
1335
1402
$ . timepicker = new Timepicker ( ) ; // singleton instance
1336
1403
$ . timepicker . version = "1.0.1" ;
1337
1404
1338
- } ) ( jQuery ) ;
1405
+ } ) ( jQuery ) ;
0 commit comments