docs: function (f, s, o) {
  
  			// pattern for standard and localized AM/PM markers
  			var getPatternAmpm = function (amNames, pmNames) {
  				var markers = [];
  				if (amNames) {
  					$.merge(markers, amNames);
  				}
  				if (pmNames) {
  					$.merge(markers, pmNames);
  				}
  				markers = $.map(markers, function (val) {
  					return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&');
  				});
  				return '(' + markers.join('|') + ')?';
  			};
  
  			// figure out position of time elements.. cause js cant do named captures
  			var getFormatPositions = function (timeFormat) {
  				var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g),
  					orders = {
  						h: -1,
  						m: -1,
  						s: -1,
  						l: -1,
  						c: -1,
  						t: -1,
  						z: -1
  					};
  
  				if (finds) {
  					for (var i = 0; i < finds.length; i++) {
  						if (orders[finds[i].toString().charAt(0)] === -1) {
  							orders[finds[i].toString().charAt(0)] = i + 1;
  						}
  					}
  				}
  				return orders;
  			};
  
  			var regstr = '^' + f.toString()
  					.replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {
  							var ml = match.length;
  							switch (match.charAt(0).toLowerCase()) {
  							case 'h':
  								return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';
  							case 'm':
  								return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';
  							case 's':
  								return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';
  							case 'l':
  								return '(\\d?\\d?\\d)';
  							case 'c':
  								return '(\\d?\\d?\\d)';
  							case 'z':
  								return '(z|[-+]\\d\\d:?\\d\\d|\\S+)?';
  							case 't':
  								return getPatternAmpm(o.amNames, o.pmNames);
  							default:    // literal escaped in quotes
  								return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?';
  							}
  						})
  					.replace(/\s/g, '\\s?') +
  					o.timeSuffix + '$',
  				order = getFormatPositions(f),
  				ampm = '',
  				treg;
  
  			treg = s.match(new RegExp(regstr, 'i'));
  
  			var resTime = {
  				hour: 0,
  				minute: 0,
  				second: 0,
  				millisec: 0,
  				microsec: 0
  			};
  
  			if (treg) {
  				if (order.t !== -1) {
  					if (treg[order.t] === undefined || treg[order.t].length === 0) {
  						ampm = '';
  						resTime.ampm = '';
  					} else {
  						ampm = $.inArray(treg[order.t].toUpperCase(), $.map(o.amNames, function (x,i) { return x.toUpperCase(); })) !== -1 ? 'AM' : 'PM';
  						resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0];
  					}
  				}
  
  				if (order.h !== -1) {
  					if (ampm === 'AM' && treg[order.h] === '12') {
  						resTime.hour = 0; // 12am = 0 hour
  					} else {
  						if (ampm === 'PM' && treg[order.h] !== '12') {
  							resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12
  						} else {
  							resTime.hour = Number(treg[order.h]);
  						}
  					}
  				}
  
  				if (order.m !== -1) {
  					resTime.minute = Number(treg[order.m]);
  				}
  				if (order.s !== -1) {
  					resTime.second = Number(treg[order.s]);
  				}
  				if (order.l !== -1) {
  					resTime.millisec = Number(treg[order.l]);
  				}
  				if (order.c !== -1) {
  					resTime.microsec = Number(treg[order.c]);
  				}
  				if (order.z !== -1 && treg[order.z] !== undefined) {
  					resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]);
  				}
  
  
  				return resTime;
  			}
  			return false;
  		}