时间控件源码解读

1.DateTimePicker

优点:支持html配置联动时间,通过startend属性约定当前输入框为起始时间或结束时间,startendelem约定另一个联动的时间输入框;

缺点:html配置和js配置在DataTiemPicker构造函数中进行比较后,进而影响方法的执行,过高的耦合度使代码的可读性(主要是数据缓存、flag标志、条件过多)变差。

/**
 * Object.keys() 返回参数可被枚举的属性;
 *
 * $(this).prop("tagName") 获取元素的标签名;
 *
 * $(oDTP.settings.parentElement).on ("focus", sel, {"obj": oDTP}, oDTP._inputFieldFocus);
 * 通过event.data获取绑定事件传递的数据,也即构造函数DateTimePicker的实例;
 *
 * this关键字指向问题???
 * 绑定事件调用构造函数的方法时,this关键字指向被绑定的jquery元素;
 * 构造函数的方法再次执行构造函数的另一方法,另一方法里,this关键字指向构造函数的实例;
 *
 * (dDate1.getTime() - dDate2.getTime()) / 864E5 事件戳比较时为位操作符???
 */

/**
 * 设计差的一面
 * 默认配置项和html属性配置多次提取后,才能判断用户的确切配置;
 * 应该将用户配置混入默认配置,执行方法直接获取该配置,不必多次比较后获取;
 */

/**
 * this.oData.oInputElement触发的输入框元素,时间面板初次显示时赋值;
 * 
 * this.oData.sArrInputDateFormats数组形式储存各日期显示格式;
 * this.oData.sArrInputTimeFormats数组形式储存各时间显示格式;
 * this.oData.sArrInputDateTimeFormats数组形式储存各日期时间显示格式;
 * this.oData.bArrMatchFormat以数组形式储存最终的时间显示格式与oData.sArrInputDateFormats等的匹配程度;
 * this.oData.bDateMode记录时间显示格式为日期类型;
 * this.oData.bTimeMode记录时间显示格式为时间类型;
 * this.oData.bDateTimeMode记录时间显示格式为日期加时间类型;
 *
 * this.oData.dMinValue获取用户配置的最小值,或者获取并设置联动时间的起始时间;
 * this.oData.dMaxValue获取用户配置的最大值,或者获取并设置联动时间的结束时间;
 * this.oData.dCurrentDate获取触发输入框的初始时间;
 * this.oData.iCurrentDay等,以触发元素输入框中的值或当前时间设置iCurrentDay等;
 * 		_setCurrentDate方法中,通过与最大最小值比较,更新dCurrentDate、iCurrentDay,使其不超过时间边际;
 * 		_getValuesFromInputBoxes方法中,获取时间面板各列年月日时分秒的值,更新this.oData.iCurrentYear等;
 *
 * this.settings.buttonsToDisplay以数组形式约定按钮的显示情况;
 */

$.DateTimePicker = $.DateTimePicker || {

	name: "DateTimePicker",

	i18n: {}, // Internationalization Objects

	defaults:  //Plugin Defaults
	{
		mode: "date",
		defaultDate: null,

		dateSeparator: "-",
		timeSeparator: ":",
		timeMeridiemSeparator: " ",
		dateTimeSeparator: " ",
		monthYearSeparator: " ",

		dateTimeFormat: "dd-MM-yyyy HH:mm",
		dateFormat: "dd-MM-yyyy",
		timeFormat: "HH:mm",

		maxDate: null,
		minDate:  null,

		maxTime: null,
		minTime: null,

		maxDateTime: null,
		minDateTime: null,

		shortDayNames: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
		fullDayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
		shortMonthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
		fullMonthNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
		labels: null, /*{"year": "Year", "month": "Month", "day": "Day", "hour": "Hour", "minutes": "Minutes", "seconds": "Seconds", "meridiem": "Meridiem"}*/

		minuteInterval: 1,
		roundOffMinutes: true,

		secondsInterval: 1,
		roundOffSeconds: true,

		titleContentDate: "Set Date",
		titleContentTime: "Set Time",
		titleContentDateTime: "Set Date & Time",

		buttonsToDisplay: ["HeaderCloseButton", "SetButton", "ClearButton"],
		setButtonContent: "Set",
		clearButtonContent: "Clear",
    	incrementButtonContent: "+",
    	decrementButtonContent: "-",
    	// +、-按钮点击时是否更新触发元素时间输入框的值
		setValueInTextboxOnEveryClick: false,

		animationDuration: 400,

		isPopup: true,
		parentElement: "body",

		language: "",

		init: null, // init(oDateTimePicker)
		addEventHandlers: null,  // addEventHandlers(oDateTimePicker)
		beforeShow: null,  // beforeShow(oInputElement)
		afterShow: null,  // afterShow(oInputElement)
		beforeHide: null,  // beforeHide(oInputElement)
		afterHide: null,  // afterHide(oInputElement)
		buttonClicked: null,  // buttonClicked(sButtonType, oInputElement) where sButtonType = "SET"|"CLEAR"|"CANCEL"|"TAB"
		settingValueOfElement: null, // settingValueOfElement(sValue, dDateTime, oInputElement)
		// formatHumanDate当存在该配置时,以显示时间为准,格式化时间面板的标题
		formatHumanDate: null,  // formatHumanDate(oDateTime, sMode, sFormat)

		parseDateTimeString: null, // parseDateTimeString(sDateTime, sMode, oInputField)
		formatDateTimeString: null, // formatDateTimeString(oDateTime, sMode, oInputField)
	},

	dataObject: // Temporary Variables For Calculation Specific to DateTimePicker Instance
	{

		dCurrentDate: new Date(),
		iCurrentDay: 0,
		iCurrentMonth: 0,
		iCurrentYear: 0,
		iCurrentHour: 0,
		iCurrentMinutes: 0,
		iCurrentSeconds: 0,
		sCurrentMeridiem: "",
		iMaxNumberOfDays: 0,

		sDateFormat: "",
		sTimeFormat: "",
		sDateTimeFormat: "",

		dMinValue: null,
		dMaxValue: null,

		sArrInputDateFormats: [],
		sArrInputTimeFormats: [],
		sArrInputDateTimeFormats: [],

		bArrMatchFormat: [],
		bDateMode: false,
		bTimeMode: false,
		bDateTimeMode: false,

		oInputElement: null,

		iTabIndex: 0,
		bElemFocused: false,

		bIs12Hour: false
	}

};

$.cf = {

	_isValid: function(sValue)
	{
		return (sValue !== undefined && sValue !== null && sValue !== "");
	},

	_compare: function(sString1, sString2)
	{
		var bString1 = (sString1 !== undefined && sString1 !== null),
		bString2 = (sString2 !== undefined && sString2 !== null);
		if(bString1 && bString2)
		{
			if(sString1.toLowerCase() === sString2.toLowerCase())
				return true;
			else
				return false;
		}
		else
			return false;
	}

};

(function (factory)
{
    if(typeof define === 'function' && define.amd)
    {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    }
    else if(typeof exports === 'object')
    {
        // Node/CommonJS
        module.exports = factory(require('jquery'));
    }
    else
    {
        // Browser globals
        factory(jQuery);
    }
}(function ($)
{
	"use strict";

	function DateTimePicker(element, options)
	{
		this.element = element;

		var sLanguage = "";
		sLanguage = ($.cf._isValid(options) && $.cf._isValid(options.language)) ? options.language : $.DateTimePicker.defaults.language;
		this.settings = $.extend({}, $.DateTimePicker.defaults, $.DateTimePicker.i18n[sLanguage], options);
		this.options = options;

		this.oData = $.extend({}, $.DateTimePicker.dataObject);
		this._defaults = $.DateTimePicker.defaults;
		this._name = $.DateTimePicker.name;

		this.init();
	}

	$.fn.DateTimePicker = function (options)
	{
		var oDTP = $(this).data(),
		sArrDataKeys = oDTP ? Object.keys(oDTP) : [],
		iKey, sKey;

		if(typeof options === "string")
		{
			if($.cf._isValid(oDTP))
			{
				if(options === "destroy")
				{
					if(sArrDataKeys.length > 0)
					{
						for(iKey in sArrDataKeys)
						{
							sKey = sArrDataKeys[iKey];
							if(sKey.search("plugin_DateTimePicker") !== -1)
							{
								$(document).unbind("click.DateTimePicker");
								$(document).unbind("keydown.DateTimePicker");
								$(document).unbind("keyup.DateTimePicker");

								$(this).children().remove();
								$(this).removeData();
								$(this).unbind();
								$(this).removeClass("dtpicker-overlay dtpicker-mobile");

								oDTP = oDTP[sKey];

								console.log("Destroyed DateTimePicker Object");
								console.log(oDTP);

								break;
							}
						}
					}
					else
					{
						console.log("No DateTimePicker Object Defined For This Element");
					}
				}
				else if(options === "object")// 获取实例
				{
					if(sArrDataKeys.length > 0)
					{
						for(iKey in sArrDataKeys)
						{
							sKey = sArrDataKeys[iKey];
							if(sKey.search("plugin_DateTimePicker") !== -1)
							{
								return oDTP[sKey];
							}
						}
					}
					else
					{
						console.log("No DateTimePicker Object Defined For This Element");
					}
				}
			}
		}
		else
		{
			return this.each(function()
			{
				$.removeData(this, "plugin_DateTimePicker");
				if(!$.data(this, "plugin_DateTimePicker"))
					$.data(this, "plugin_DateTimePicker", new DateTimePicker(this, options));
			});
		}
	};

	DateTimePicker.prototype = {

		// Public Method
		init: function ()
		{
			var oDTP = this;

			oDTP._setDateFormatArray(); // Set DateFormatArray
			oDTP._setTimeFormatArray(); // Set TimeFormatArray
			oDTP._setDateTimeFormatArray(); // Set DateTimeFormatArray

			if(oDTP.settings.isPopup)
			{
				oDTP._createPicker();
				$(oDTP.element).addClass("dtpicker-mobile");
			}

			if(oDTP.settings.init)
				oDTP.settings.init.call(oDTP);

			oDTP._addEventHandlersForInput();
		},

		// 时间显示格式,date为年月日,time时分秒,datetime年月日时分秒
		_setDateFormatArray: function()
		{
			var oDTP = this;

			oDTP.oData.sArrInputDateFormats = [];
			var sDate = "";

			//  0 - "dd-MM-yyyy"
			sDate = "dd" + oDTP.settings.dateSeparator + "MM" + oDTP.settings.dateSeparator + "yyyy";
			oDTP.oData.sArrInputDateFormats.push(sDate);

			//  1 - "MM-dd-yyyy"
			sDate = "MM" + oDTP.settings.dateSeparator + "dd" + oDTP.settings.dateSeparator + "yyyy";
			oDTP.oData.sArrInputDateFormats.push(sDate);

			//  2 - "yyyy-MM-dd"
			sDate = "yyyy" + oDTP.settings.dateSeparator + "MM" + oDTP.settings.dateSeparator + "dd";
			oDTP.oData.sArrInputDateFormats.push(sDate);

			//  3 - "dd-MMM-yyyy"
			sDate = "dd" + oDTP.settings.dateSeparator + "MMM" + oDTP.settings.dateSeparator + "yyyy";
			oDTP.oData.sArrInputDateFormats.push(sDate);

			//  4 - "MM yyyy"
			sDate = "MM" + oDTP.settings.monthYearSeparator + "yyyy";
			oDTP.oData.sArrInputDateFormats.push(sDate);

			//  5 - "MMM yyyy"
			sDate = "MMM" + oDTP.settings.monthYearSeparator + "yyyy";
			oDTP.oData.sArrInputDateFormats.push(sDate);

			//  6 - "MMM yyyy"
			sDate = "MMMM" + oDTP.settings.monthYearSeparator + "yyyy";
			oDTP.oData.sArrInputDateFormats.push(sDate);
		},

		_setTimeFormatArray: function()
		{
			var oDTP = this;

			oDTP.oData.sArrInputTimeFormats = [];
			var sTime = "";

			//  0 - "hh:mm:ss AA"
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeSeparator + "ss" + oDTP.settings.timeMeridiemSeparator + "AA";
			oDTP.oData.sArrInputTimeFormats.push(sTime);

			//  1 - "HH:mm:ss"
			sTime = "HH" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeSeparator + "ss";
			oDTP.oData.sArrInputTimeFormats.push(sTime);

			//  2 - "hh:mm AA"
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeMeridiemSeparator + "AA";
			oDTP.oData.sArrInputTimeFormats.push(sTime);

			//  3 - "HH:mm"
			sTime = "HH" + oDTP.settings.timeSeparator + "mm";
			oDTP.oData.sArrInputTimeFormats.push(sTime);
		},

		_setDateTimeFormatArray: function()
		{
			var oDTP = this;

			oDTP.oData.sArrInputDateTimeFormats = [];
			var sDate = "", sTime = "", sDateTime = "";

			//  0 - "dd-MM-yyyy HH:mm:ss"
			sDate = "dd" + oDTP.settings.dateSeparator + "MM" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "HH" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeSeparator + "ss";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  1 - "dd-MM-yyyy hh:mm:ss AA"
			sDate = "dd" + oDTP.settings.dateSeparator + "MM" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeSeparator + "ss" + oDTP.settings.timeMeridiemSeparator + "AA";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  2 - "MM-dd-yyyy HH:mm:ss"
			sDate = "MM" + oDTP.settings.dateSeparator + "dd" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "HH" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeSeparator + "ss";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  3 - "MM-dd-yyyy hh:mm:ss AA"
			sDate = "MM" + oDTP.settings.dateSeparator + "dd" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeSeparator + "ss" + oDTP.settings.timeMeridiemSeparator + "AA";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  4 - "yyyy-MM-dd HH:mm:ss"
			sDate = "yyyy" + oDTP.settings.dateSeparator + "MM" + oDTP.settings.dateSeparator + "dd";
			sTime = "HH" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeSeparator + "ss";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  5 - "yyyy-MM-dd hh:mm:ss AA"
			sDate = "yyyy" + oDTP.settings.dateSeparator + "MM" + oDTP.settings.dateSeparator + "dd";
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeSeparator + "ss" + oDTP.settings.timeMeridiemSeparator + "AA";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  6 - "dd-MMM-yyyy hh:mm:ss"
			sDate = "dd" + oDTP.settings.dateSeparator + "MMM" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeSeparator + "ss";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  7 - "dd-MMM-yyyy hh:mm:ss AA"
			sDate = "dd" + oDTP.settings.dateSeparator + "MMM" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeSeparator + "ss" + oDTP.settings.timeMeridiemSeparator + "AA";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//--------------

			//  8 - "dd-MM-yyyy HH:mm"
			sDate = "dd" + oDTP.settings.dateSeparator + "MM" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "HH" + oDTP.settings.timeSeparator + "mm";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  9 - "dd-MM-yyyy hh:mm AA"
			sDate = "dd" + oDTP.settings.dateSeparator + "MM" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeMeridiemSeparator + "AA";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  10 - "MM-dd-yyyy HH:mm"
			sDate = "MM" + oDTP.settings.dateSeparator + "dd" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "HH" + oDTP.settings.timeSeparator + "mm";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  11 - "MM-dd-yyyy hh:mm AA"
			sDate = "MM" + oDTP.settings.dateSeparator + "dd" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeMeridiemSeparator + "AA";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  12 - "yyyy-MM-dd HH:mm"
			sDate = "yyyy" + oDTP.settings.dateSeparator + "MM" + oDTP.settings.dateSeparator + "dd";
			sTime = "HH" + oDTP.settings.timeSeparator + "mm";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  13 - "yyyy-MM-dd hh:mm AA"
			sDate = "yyyy" + oDTP.settings.dateSeparator + "MM" + oDTP.settings.dateSeparator + "dd";
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeMeridiemSeparator + "AA";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  14 - "dd-MMM-yyyy hh:mm"
			sDate = "dd" + oDTP.settings.dateSeparator + "MMM" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "hh" + oDTP.settings.timeSeparator + "mm";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);

			//  15 - "dd-MMM-yyyy hh:mm AA"
			sDate = "dd" + oDTP.settings.dateSeparator + "MMM" + oDTP.settings.dateSeparator + "yyyy";
			sTime = "hh" + oDTP.settings.timeSeparator + "mm" + oDTP.settings.timeMeridiemSeparator + "AA";
			sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
			oDTP.oData.sArrInputDateTimeFormats.push(sDateTime);
		},

		// 根据时间显示内容(有否时分秒),调整oArrInput为相应的时间显示格式sArrInputDateFormats等;
		// 实例this.oData.bDateMode、this.oData.bTimeMode、this.oData.bDateTimeMode记录哪种时间显示格式;
		// 实例this.oData.bArrMatchFormat以数组形式记录oArrInput中匹配的值为true,不匹配的为false;
		// 目的是据此设置页面中的样式,添加day、month等标志,以及输入框的输出时间显示;
		_matchFormat: function(sMode, sFormat)
		{
			var oDTP = this;

			oDTP.oData.bArrMatchFormat = [];
			oDTP.oData.bDateMode = false;
			oDTP.oData.bTimeMode = false;
			oDTP.oData.bDateTimeMode = false;
			var oArrInput = [], iTempIndex;

			sMode = $.cf._isValid(sMode) ? sMode : oDTP.settings.mode;
			if($.cf._compare(sMode, "date"))
			{
				sFormat = $.cf._isValid(sFormat) ? sFormat : oDTP.oData.sDateFormat;
				oDTP.oData.bDateMode = true;
				oArrInput = oDTP.oData.sArrInputDateFormats;
			}
			else if($.cf._compare(sMode, "time"))
			{
				sFormat = $.cf._isValid(sFormat) ? sFormat : oDTP.oData.sTimeFormat;
				oDTP.oData.bTimeMode = true;
				oArrInput = oDTP.oData.sArrInputTimeFormats;
			}
			else if($.cf._compare(sMode, "datetime"))
			{
				sFormat = $.cf._isValid(sFormat) ? sFormat : oDTP.oData.sDateTimeFormat;
				oDTP.oData.bDateTimeMode = true;
				oArrInput = oDTP.oData.sArrInputDateTimeFormats;
			}

			for(iTempIndex = 0; iTempIndex < oArrInput.length; iTempIndex++)
			{
				oDTP.oData.bArrMatchFormat.push(
					$.cf._compare(sFormat, oArrInput[iTempIndex])
				);
			}
		},

		// 调用this._matchFormat设置this.oData.bArrMatchForma数据,供样式设置时使用;
		_setMatchFormat: function(iArgsLength, sMode, sFormat)
		{
			var oDTP = this;

			if(iArgsLength > 0)
				oDTP._matchFormat(sMode, sFormat);
		},

		// 生成事件面板框架结构,外层包裹元素和供点击隐藏的浮层
		_createPicker: function()
		{
			var oDTP = this;

			$(oDTP.element).addClass("dtpicker-overlay");
			$(".dtpicker-overlay").click(function(e)
			{
				oDTP._hidePicker("");
			});

			var sTempStr = "";
			sTempStr += "<div class='dtpicker-bg'>";
			sTempStr += "<div class='dtpicker-cont'>";
			sTempStr += "<div class='dtpicker-content'>";
			sTempStr += "<div class='dtpicker-subcontent'>";
			sTempStr += "</div>";
			sTempStr += "</div>";
			sTempStr += "</div>";
			sTempStr += "</div>";
			$(oDTP.element).html(sTempStr);
		},

		// 将输入框的type="date"属性转化成data-field="date"属性,type值替换成text;
		// 输入框绑定获得焦点以及点击事件,构造函数的实例通过绑定事件传参带入;
		_addEventHandlersForInput: function()
		{
			var oDTP = this;

			oDTP.oData.oInputElement = null;

			$(oDTP.settings.parentElement).find("input[type='date'], input[type='time'], input[type='datetime']").each(function()
			{
				$(this).attr("data-field", $(this).attr("type"));
				$(this).attr("type", "text");
			});

			var sel = "[data-field='date'], [data-field='time'], [data-field='datetime']";
			$(oDTP.settings.parentElement).off("focus", sel, oDTP._inputFieldFocus);
			// 构造函数的实例通过绑定事件传参带入
			$(oDTP.settings.parentElement).on ("focus", sel, {"obj": oDTP}, oDTP._inputFieldFocus);

			$(oDTP.settings.parentElement).off("click", sel, oDTP._inputFieldClick);
			$(oDTP.settings.parentElement).on ("click", sel, {"obj": oDTP}, oDTP._inputFieldClick);

			if(oDTP.settings.addEventHandlers) //this is not an event-handler really. Its just a function called
				oDTP.settings.addEventHandlers.call(oDTP); // which could add EventHandlers
		},

		// 输入框获得焦点时触发函数;
		_inputFieldFocus: function(e)
		{
			var oDTP = e.data.obj;
			oDTP.showDateTimePicker(this);
			oDTP.oData.bMouseDown = false;
		},

		// 输入框获得被点击时触发函数;
		_inputFieldClick: function(e)// 通过绑定事件调用构造函数的方法时,this关键字变作被绑定元素的jquery对象
		{
          	var oDTP = e.data.obj;
			if(!$.cf._compare($(this).prop("tagName"), "input"))
			{
				oDTP.showDateTimePicker(this);// 再次调用实例的方法时,this关键字又指向该实例???
			}
			e.stopPropagation();
		},

		// Public Method
		getDateObjectForInputField: function(oInputField)
		{
			var oDTP = this;

			if($.cf._isValid(oInputField))
			{
				var sDateTime = oDTP._getValueOfElement(oInputField),
				sMode = $(oInputField).data("field"),
				sFormat = "",
				dInput;

				if(!$.cf._isValid(sMode))
		    		sMode = oDTP.settings.mode;
		    	if(! oDTP.settings.formatDateTimeString)
		    	{
		    		sFormat = $(oInputField).data("format");
			    	if(!$.cf._isValid(sFormat))
			    	{
				    	if($.cf._compare(sMode, "date"))
				    		sFormat = oDTP.settings.dateFormat;
				    	else if($.cf._compare(sMode, "time"))
				        	sFormat = oDTP.settings.timeFormat;
				        else if($.cf._compare(sMode, "datetime"))
				        	sFormat = oDTP.settings.dateTimeFormat;
				    }

				    oDTP._matchFormat(sMode, sFormat);

			    	if($.cf._compare(sMode, "date"))
			    		dInput = oDTP._parseDate(sDateTime);
			    	else if($.cf._compare(sMode, "time"))
			        	dInput = oDTP._parseTime(sDateTime);
			        else if($.cf._compare(sMode, "datetime"))
			        	dInput = oDTP._parseDateTime(sDateTime);

				}
				else
				{
					dInput = oDTP.settings.parseDateTimeString.call(oDTP, sDateTime, sMode, $(oInputField));
				}

		        return dInput;
			}
		},

		// Public Method
		setDateTimeStringInInputField: function(oInputField, dInput)
		{
			var oDTP = this;

			dInput = dInput || oDTP.oData.dCurrentDate;

			var oArrElements;
			if($.cf._isValid(oInputField))
			{
				oArrElements = [];
				if(typeof oInputField === "string")
					oArrElements.push(oInputField);
				else if(typeof oInputField === "object")
					oArrElements = oInputField;
			}
			else
			{
				if($.cf._isValid(oDTP.settings.parentElement))
				{
					oArrElements = $(oDTP.settings.parentElement).find("[data-field='date'], [data-field='time'], [data-field='datetime']");
				}
				else
				{
					oArrElements = $("[data-field='date'], [data-field='time'], [data-field='datetime']");
				}
			}

			oArrElements.each(function()
			{
				var oElement = this,
				sMode, sFormat, bIs12Hour, sOutput;

		        sMode = $(oElement).data("field");
		        if(!$.cf._isValid(sMode))
		    		sMode = oDTP.settings.mode;

		    	sFormat = "Custom";
		    	bIs12Hour = false;
		    	if(! oDTP.settings.formatDateTimeString)
		    	{
			    	sFormat = $(oElement).data("format");
			    	if(!$.cf._isValid(sFormat))
			    	{
				    	if($.cf._compare(sMode, "date"))
				    		sFormat = oDTP.settings.dateFormat;
				    	else if($.cf._compare(sMode, "time"))
				        	sFormat = oDTP.settings.timeFormat;
				        else if($.cf._compare(sMode, "datetime"))
				        	sFormat = oDTP.settings.dateTimeFormat;
				    }

				    bIs12Hour = oDTP.getIs12Hour(sMode, sFormat);
				}

				sOutput = oDTP._setOutput(sMode, sFormat, bIs12Hour, dInput, oElement);
				oDTP._setValueOfElement(sOutput, $(oElement));
			});
		},

		// Public Method
		getDateTimeStringInFormat: function(sMode, sFormat, dInput)
		{
			var oDTP = this;
			return oDTP._setOutput(sMode, sFormat, oDTP.getIs12Hour(sMode, sFormat), dInput);
		},

		// 显示或隐藏时间面板
		showDateTimePicker: function(oElement)
		{
			var oDTP = this;

			if(oDTP.oData.oInputElement !== null)
				oDTP._hidePicker(0, oElement);
			else
				oDTP._showPicker(oElement);
		},

		// 填充触发元素输入框,同时执行buttonClicked("TAB",$trigger)函数,隐藏时间面板
		_setButtonAction: function(bFromTab)
		{
			var oDTP = this;

			if(oDTP.oData.oInputElement !== null)
			{
				oDTP._setValueOfElement(oDTP._setOutput());

				if(bFromTab)
				{
					if(oDTP.settings.buttonClicked)
						oDTP.settings.buttonClicked.call(oDTP, "TAB", oDTP.oData.oInputElement);
					oDTP._hidePicker(0);
				}
				else
					oDTP._hidePicker("");
			}
		},

		// 以一定格式获取时间输出,并返回
		_setOutput: function(sMode, sFormat, bIs12Hour, dCurrentDate, oElement)
		{
			var oDTP = this;

			dCurrentDate = $.cf._isValid(dCurrentDate) ? dCurrentDate : oDTP.oData.dCurrentDate;
			bIs12Hour = bIs12Hour || oDTP.oData.bIs12Hour;

			var oDTV = oDTP._setVariablesForDate(dCurrentDate, true, true);

			var sOutput = "",
			oFDate = oDTP._formatDate(oDTV),
			oFTime = oDTP._formatTime(oDTV),
			oFDT = $.extend({}, oFDate, oFTime),

			sDateStr = "", sTimeStr = "",
			iArgsLength = Function.length,
			bAddSeconds;

			if(oDTP.settings.formatDateTimeString)
			{
				sOutput = oDTP.settings.formatDateTimeString.call(oDTP, oFDT, sMode, oElement);
			}
			else
			{
				// Set bDate, bTime, bDateTime & bArrMatchFormat based on arguments of this function
				oDTP._setMatchFormat(iArgsLength, sMode, sFormat);

				if(oDTP.oData.bDateMode)
				{
					if(oDTP.oData.bArrMatchFormat[0])
					{
						sOutput = oFDT.dd + oDTP.settings.dateSeparator + oFDT.MM + oDTP.settings.dateSeparator + oFDT.yyyy;
					}
					else if(oDTP.oData.bArrMatchFormat[1])
					{
						sOutput = oFDT.MM + oDTP.settings.dateSeparator + oFDT.dd + oDTP.settings.dateSeparator + oFDT.yyyy;
					}
					else if(oDTP.oData.bArrMatchFormat[2])
					{
						sOutput = oFDT.yyyy + oDTP.settings.dateSeparator + oFDT.MM + oDTP.settings.dateSeparator + oFDT.dd;
					}
					else if(oDTP.oData.bArrMatchFormat[3])
					{
						sOutput = oFDT.dd + oDTP.settings.dateSeparator + oFDT.monthShort + oDTP.settings.dateSeparator + oFDT.yyyy;
					}
					else if(oDTP.oData.bArrMatchFormat[4])
					{
						sOutput = oFDT.MM + oDTP.settings.monthYearSeparator + oFDT.yyyy;
					}
					else if(oDTP.oData.bArrMatchFormat[5])
					{
						sOutput = oFDT.monthShort + oDTP.settings.monthYearSeparator + oFDT.yyyy;
					}
					else if(oDTP.oData.bArrMatchFormat[6])
					{
						sOutput = oFDT.month + oDTP.settings.monthYearSeparator + oFDT.yyyy;
					}
				}
				else if(oDTP.oData.bTimeMode)
				{
					if(oDTP.oData.bArrMatchFormat[0])
					{
						sOutput = oFDT.hh + oDTP.settings.timeSeparator + oFDT.mm + oDTP.settings.timeSeparator + oFDT.ss + oDTP.settings.timeMeridiemSeparator + oFDT.ME;
					}
					else if(oDTP.oData.bArrMatchFormat[1])
					{
						sOutput = oFDT.HH + oDTP.settings.timeSeparator + oFDT.mm + oDTP.settings.timeSeparator + oFDT.ss;
					}
					else if(oDTP.oData.bArrMatchFormat[2])
					{
						sOutput = oFDT.hh + oDTP.settings.timeSeparator + oFDT.mm + oDTP.settings.timeMeridiemSeparator + oFDT.ME;
					}
					else if(oDTP.oData.bArrMatchFormat[3])
					{
						sOutput = oFDT.HH + oDTP.settings.timeSeparator + oFDT.mm;
					}
				}
				else if(oDTP.oData.bDateTimeMode)
				{
					// Date Part - "dd-MM-yyyy"
					if(oDTP.oData.bArrMatchFormat[0] ||
						oDTP.oData.bArrMatchFormat[1] ||
						oDTP.oData.bArrMatchFormat[8] ||
						oDTP.oData.bArrMatchFormat[9])
					{
						sDateStr = oFDT.dd + oDTP.settings.dateSeparator + oFDT.MM + oDTP.settings.dateSeparator + oFDT.yyyy;
					}
					// Date Part - "MM-dd-yyyy"
					else if(oDTP.oData.bArrMatchFormat[2] ||
							oDTP.oData.bArrMatchFormat[3] ||
							oDTP.oData.bArrMatchFormat[10] ||
							oDTP.oData.bArrMatchFormat[11])
					{
						sDateStr = oFDT.MM + oDTP.settings.dateSeparator + oFDT.dd + oDTP.settings.dateSeparator + oFDT.yyyy;
					}
					// Date Part - "yyyy-MM-dd"
					else if(oDTP.oData.bArrMatchFormat[4] ||
							oDTP.oData.bArrMatchFormat[5] ||
							oDTP.oData.bArrMatchFormat[12] ||
							oDTP.oData.bArrMatchFormat[13])
					{
						sDateStr = oFDT.yyyy + oDTP.settings.dateSeparator + oFDT.MM + oDTP.settings.dateSeparator + oFDT.dd;
					}
					// Date Part - "dd-MMM-yyyy"
					else if(oDTP.oData.bArrMatchFormat[6] ||
							oDTP.oData.bArrMatchFormat[7] ||
							oDTP.oData.bArrMatchFormat[14] ||
							oDTP.oData.bArrMatchFormat[15])
					{
						sDateStr = oFDT.dd + oDTP.settings.dateSeparator + oFDT.monthShort + oDTP.settings.dateSeparator + oFDT.yyyy;
					}

					bAddSeconds = oDTP.oData.bArrMatchFormat[0] ||
							oDTP.oData.bArrMatchFormat[1] ||
							oDTP.oData.bArrMatchFormat[2] ||
							oDTP.oData.bArrMatchFormat[3] ||
							oDTP.oData.bArrMatchFormat[4] ||
							oDTP.oData.bArrMatchFormat[5] ||
							oDTP.oData.bArrMatchFormat[6] ||
							oDTP.oData.bArrMatchFormat[7];
					if(bIs12Hour)
					{
						if(bAddSeconds)
						{
							sTimeStr = oFDT.hh + oDTP.settings.timeSeparator + oFDT.mm + oDTP.settings.timeSeparator + oFDT.ss + oDTP.settings.timeMeridiemSeparator + oFDT.ME;
						}
						else
						{
							sTimeStr = oFDT.hh + oDTP.settings.timeSeparator + oFDT.mm + oDTP.settings.timeMeridiemSeparator + oFDT.ME;
						}
					}
					else
					{
						if(bAddSeconds)
						{
							sTimeStr = oFDT.HH + oDTP.settings.timeSeparator + oFDT.mm + oDTP.settings.timeSeparator + oFDT.ss;
						}
						else
						{
							sTimeStr = oFDT.HH + oDTP.settings.timeSeparator + oFDT.mm;
						}
					}

					if(sDateStr !== "" && sTimeStr !== "")
						sOutput = sDateStr + oDTP.settings.dateTimeSeparator + sTimeStr;
				}

				// Reset bDate, bTime, bDateTime & bArrMatchFormat to original values
				oDTP._setMatchFormat(iArgsLength);
			}

			return sOutput;
		},

		// clear按钮实现
		_clearButtonAction: function()
		{
			var oDTP = this;

			if(oDTP.oData.oInputElement !== null)
			{
				oDTP._setValueOfElement("");
			}
			oDTP._hidePicker("");
		},

		// setValueInTextboxOnEveryClick为真时,+、-按钮点击更新触发输入框的值
		_setOutputOnIncrementOrDecrement: function()
		{
			var oDTP = this;

			if($.cf._isValid(oDTP.oData.oInputElement) && oDTP.settings.setValueInTextboxOnEveryClick)
			{
				oDTP._setValueOfElement(oDTP._setOutput());
			}
		},

		// 展示时间面板
		_showPicker: function(oElement)
		{
			var oDTP = this;

			if(oDTP.oData.oInputElement === null)
			{
				oDTP.oData.oInputElement = oElement;
				oDTP.oData.iTabIndex = parseInt($(oElement).attr("tabIndex"));

				// 用户配置项,field时间显示格式,min最小值,max最大值,format、view???
				// view内嵌或弹窗显示;
				// startendelem时间联动时的相关输入框,startend现输入框是起始时间还是结束时间;
				var sMode = $(oElement).data("field") || "",
				sMinValue = $(oElement).data("min") || "",
				sMaxValue = $(oElement).data("max") || "",
				sFormat = $(oElement).data("format") || "",
				sView = $(oElement).data("view") || "",
				sStartEnd = $(oElement).data("startend") || "",
				sStartEndElem = $(oElement).data("startendelem") || "",
				sCurrent = oDTP._getValueOfElement(oElement) || "";

				if(sView !== "")
				{
					if($.cf._compare(sView, "Popup"))
						oDTP.setIsPopup(true);
					else
						oDTP.setIsPopup(false);
				}

				if(!oDTP.settings.isPopup)// 用得着多次判断是否弹窗,运行效果又和setIsPopup相同???
				{
					oDTP._createPicker();

					var iElemTop = $(oDTP.oData.oInputElement).offset().top + $(oDTP.oData.oInputElement).outerHeight(),
					iElemLeft = $(oDTP.oData.oInputElement).offset().left,
					iElemWidth =  $(oDTP.oData.oInputElement).outerWidth();

					$(oDTP.element).css({position: "absolute", top: iElemTop, left: iElemLeft, width: iElemWidth, height: "auto"});
				}

				if(oDTP.settings.beforeShow)
					oDTP.settings.beforeShow.call(oDTP, oElement);

				// 用户无相应配置时,取js中的默认配置;
				// 应该将用户配置混入默认配置,执行方法直接获取该配置,不必多次比较后获取;※※※
				sMode = $.cf._isValid(sMode) ? sMode : oDTP.settings.mode;
				oDTP.settings.mode = sMode;
				if(!$.cf._isValid(sFormat))
				{
					if($.cf._compare(sMode, "date"))
						sFormat = oDTP.settings.dateFormat;
					else if($.cf._compare(sMode, "time"))
						sFormat = oDTP.settings.timeFormat;
					else if($.cf._compare(sMode, "datetime"))
						sFormat = oDTP.settings.dateTimeFormat;
				}

				oDTP._matchFormat(sMode, sFormat);

				oDTP.oData.dMinValue = null;
				oDTP.oData.dMaxValue = null;
				oDTP.oData.bIs12Hour = false;

				// 在sMinValue、sMaxValue之外在新增变量的原因也在于用户配置不能及时合并到默认配置中※※※
				var sMin, sMax,
				// sTempDate联动输入框的时间值, dTempDate格式化后的sTempDate值;
				sTempDate, dTempDate,
				sTempTime, dTempTime,
				sTempDateTime, dTempDateTime;

				// this.oData.bDateMode为真,时间显示格式为日期类型;
				if(oDTP.oData.bDateMode)
				{
					sMin = sMinValue || oDTP.settings.minDate;
					sMax = sMaxValue || oDTP.settings.maxDate;

					oDTP.oData.sDateFormat = sFormat;

					if($.cf._isValid(sMin))
						oDTP.oData.dMinValue = oDTP._parseDate(sMin);
					if($.cf._isValid(sMax))
						oDTP.oData.dMaxValue = oDTP._parseDate(sMax);

					// 时间联动相关
					if(sStartEnd !== "" && ($.cf._compare(sStartEnd, "start") || $.cf._compare(sStartEnd, "end")) && sStartEndElem !== "")
					{
						if($(sStartEndElem).length >= 1)
						{
							sTempDate = oDTP._getValueOfElement($(sStartEndElem));
							if(sTempDate !== "")
							{
								if(oDTP.settings.parseDateTimeString)
									dTempDate = oDTP.settings.parseDateTimeString.call(oDTP, sTempDate, sMode, $(sStartEndElem));
								else
									dTempDate = oDTP._parseDate(sTempDate);

								if($.cf._compare(sStartEnd, "start"))
								{
									// 当最大时间已经合并到this.oData.dMaxValue时,不必在多生歧义地判断sMax
									// 因为判断this.oData.dMaxValue是否有效和判断sMax是否有效等同
									if($.cf._isValid(sMax))
									{
										if(oDTP._compareDates(dTempDate, oDTP.oData.dMaxValue) < 0)
											// 将现联动输入框的结束时间设为相应输入框的值
											oDTP.oData.dMaxValue = new Date(dTempDate);
									}
									else
										oDTP.oData.dMaxValue = new Date(dTempDate);
								}
								else if($.cf._compare(sStartEnd, "end"))
								{
									if($.cf._isValid(sMin))
									{
										if(oDTP._compareDates(dTempDate, oDTP.oData.dMinValue) > 0)
											oDTP.oData.dMinValue = new Date(dTempDate);
									}
									else
										oDTP.oData.dMinValue = new Date(dTempDate);
								}
							}
						}
					}

					if(oDTP.settings.parseDateTimeString)
						oDTP.oData.dCurrentDate = oDTP.settings.parseDateTimeString.call(oDTP, sCurrent, sMode, $(oElement));
					else
						oDTP.oData.dCurrentDate = oDTP._parseDate(sCurrent);

					oDTP.oData.dCurrentDate.setHours(0);
					oDTP.oData.dCurrentDate.setMinutes(0);
					oDTP.oData.dCurrentDate.setSeconds(0);
				}
				// this.oData.bTimeMode时间显示格式为时分秒形式
				else if(oDTP.oData.bTimeMode)
				{
					sMin = sMinValue || oDTP.settings.minTime;
					sMax = sMaxValue || oDTP.settings.maxTime;

					oDTP.oData.sTimeFormat = sFormat;
					oDTP.oData.bIs12Hour = oDTP.getIs12Hour();

					if($.cf._isValid(sMin))
						oDTP.oData.dMinValue = oDTP._parseTime(sMin);
					if($.cf._isValid(sMax))
						oDTP.oData.dMaxValue = oDTP._parseTime(sMax);

					if(sStartEnd !== "" && ($.cf._compare(sStartEnd, "start") || $.cf._compare(sStartEnd, "end")) && sStartEndElem !== "")
					{
						if($(sStartEndElem).length >= 1)
						{
							sTempTime = oDTP._getValueOfElement($(sStartEndElem));
							if(sTempTime !== "")
							{
								if(oDTP.settings.parseDateTimeString)
									dTempDate = oDTP.settings.parseDateTimeString.call(oDTP, sTempTime, sMode, $(sStartEndElem));
								else
									dTempTime = oDTP._parseTime(sTempTime);

								if($.cf._compare(sStartEnd, "start"))
								{
									dTempTime.setMinutes(dTempTime.getMinutes() - 1);
									if($.cf._isValid(sMax))
									{
										if(oDTP._compareTime(dTempTime, oDTP.oData.dMaxValue) === 2)
											oDTP.oData.dMaxValue = new Date(dTempTime);
									}
									else
										oDTP.oData.dMaxValue = new Date(dTempTime);
								}
								else if($.cf._compare(sStartEnd, "end"))
								{
									dTempTime.setMinutes(dTempTime.getMinutes() + 1);
									if($.cf._isValid(sMin))
									{
										if(oDTP._compareTime(dTempTime, oDTP.oData.dMinValue) === 3)
											oDTP.oData.dMinValue = new Date(dTempTime);
									}
									else
										oDTP.oData.dMinValue = new Date(dTempTime);
								}
							}
						}
					}

					if(oDTP.settings.parseDateTimeString)
						oDTP.oData.dCurrentDate = oDTP.settings.parseDateTimeString.call(oDTP, sCurrent, sMode, $(oElement));
					else
						oDTP.oData.dCurrentDate = oDTP._parseTime(sCurrent);
				}
				// this.oData.bDateTimeMode时间显示格式为日期加时分秒形式
				else if(oDTP.oData.bDateTimeMode)
				{
					sMin = sMinValue || oDTP.settings.minDateTime;
					sMax = sMaxValue || oDTP.settings.maxDateTime;

					oDTP.oData.sDateTimeFormat = sFormat;
					oDTP.oData.bIs12Hour = oDTP.getIs12Hour();

					if($.cf._isValid(sMin))
						oDTP.oData.dMinValue = oDTP._parseDateTime(sMin);
					if($.cf._isValid(sMax))
						oDTP.oData.dMaxValue = oDTP._parseDateTime(sMax);

					if(sStartEnd !== "" && ($.cf._compare(sStartEnd, "start") || $.cf._compare(sStartEnd, "end")) && sStartEndElem !== "")
					{
						if($(sStartEndElem).length >= 1)
						{
							sTempDateTime = oDTP._getValueOfElement($(sStartEndElem));
							if(sTempDateTime !== "")
							{
								if(oDTP.settings.parseDateTimeString)
									dTempDateTime = oDTP.settings.parseDateTimeString.call(oDTP, sTempDateTime, sMode, $(sStartEndElem));
								else
									dTempDateTime = oDTP._parseDateTime(sTempDateTime);

								if($.cf._compare(sStartEnd, "start"))
								{
									if($.cf._isValid(sMax))
									{
										if(oDTP._compareDateTime(dTempDateTime, oDTP.oData.dMaxValue) < 0)
											oDTP.oData.dMaxValue = new Date(dTempDateTime);
									}
									else
										oDTP.oData.dMaxValue = new Date(dTempDateTime);
								}
								else if($.cf._compare(sStartEnd, "end"))
								{
									if($.cf._isValid(sMin))
									{
										if(oDTP._compareDateTime(dTempDateTime, oDTP.oData.dMinValue) > 0)
											oDTP.oData.dMinValue = new Date(dTempDateTime);
									}
									else
										oDTP.oData.dMinValue = new Date(dTempDateTime);
								}
							}
						}
					}

					if(oDTP.settings.parseDateTimeString)
						oDTP.oData.dCurrentDate = oDTP.settings.parseDateTimeString.call(oDTP, sCurrent, sMode, $(oElement));
					else
						oDTP.oData.dCurrentDate = oDTP._parseDateTime(sCurrent);
				}

				// 触发元素输入框没有初始值时,以当前时间创建this.oData.iCurrentDay
				oDTP._setVariablesForDate();
				// 设置时间面板的大致框架后填充时间文本和标题,再设置+、-按钮是否可点选
				oDTP._modifyPicker();
				$(oDTP.element).fadeIn(oDTP.settings.animationDuration);

				if(oDTP.settings.afterShow)
				{
					setTimeout(function()
					{
						oDTP.settings.afterShow.call(oDTP, oElement);
					}, oDTP.settings.animationDuration);
				}
			}
		},

		// 隐藏时间面板,取消事件绑定,触发相应的事件
		_hidePicker: function(iDuration, oElementToShow)
		{
			var oDTP = this;
			var oElement = oDTP.oData.oInputElement;

			if(oDTP.settings.beforeHide)
				oDTP.settings.beforeHide.call(oDTP, oElement);

			if(!$.cf._isValid(iDuration))
				iDuration = oDTP.settings.animationDuration;

			if($.cf._isValid(oDTP.oData.oInputElement))
			{
				$(oDTP.oData.oInputElement).blur();
				oDTP.oData.oInputElement = null;
			}

			$(oDTP.element).fadeOut(iDuration);
			if(iDuration === 0)
			{
				$(oDTP.element).find('.dtpicker-subcontent').html("");
			}
			else
			{
				setTimeout(function()
				{
					$(oDTP.element).find('.dtpicker-subcontent').html("");
				}, iDuration);
			}

			$(document).unbind("click.DateTimePicker");
			$(document).unbind("keydown.DateTimePicker");
			$(document).unbind("keyup.DateTimePicker");

			if(oDTP.settings.afterHide)
			{
				if(iDuration === 0)
				{
					oDTP.settings.afterHide.call(oDTP, oElement);
				}
				else
				{
					setTimeout(function()
					{
						oDTP.settings.afterHide.call(oDTP, oElement);
					}, iDuration);
				}
			}

			if($.cf._isValid(oElementToShow))
				oDTP._showPicker(oElementToShow);
		},

		// 由this.oData.bArrMatchFormat设置页面中的样式(包含几列,设置列样式)以及按钮;
		// 完成时间面板大致架构的渲染,各标签未包含具体的时间内容;
		_modifyPicker: function()
		{
			var oDTP = this;

			var sTitleContent, iNumberOfColumns;
			var sArrFields = [];
			// 时间显示格式为日期类型;
			if(oDTP.oData.bDateMode)
			{
				sTitleContent = oDTP.settings.titleContentDate;
				iNumberOfColumns = 3;

				if(oDTP.oData.bArrMatchFormat[0])  // "dd-MM-yyyy"
				{
					sArrFields = ["day", "month", "year"];
				}
				else if(oDTP.oData.bArrMatchFormat[1])  // "MM-dd-yyyy"
				{
					sArrFields = ["month", "day", "year"];
				}
				else if(oDTP.oData.bArrMatchFormat[2])  // "yyyy-MM-dd"
				{
					sArrFields = ["year", "month", "day"];
				}
				else if(oDTP.oData.bArrMatchFormat[3])  // "dd-MMM-yyyy"
				{
					sArrFields = ["day", "month", "year"];
				}
				else if(oDTP.oData.bArrMatchFormat[4])  // "MM-yyyy"
				{
					iNumberOfColumns = 2;
					sArrFields = ["month", "year"];
				}
				else if(oDTP.oData.bArrMatchFormat[5])  // "MMM yyyy"
				{
					iNumberOfColumns = 2;
					sArrFields = ["month", "year"];
				}
				else if(oDTP.oData.bArrMatchFormat[6])  // "MMMM yyyy"
				{
					iNumberOfColumns = 2;
					sArrFields = ["month", "year"];
				}
			}
			// 时间显示格式为时分秒类型;
			else if(oDTP.oData.bTimeMode)
			{
				sTitleContent = oDTP.settings.titleContentTime;
				if(oDTP.oData.bArrMatchFormat[0]) // hh:mm:ss AA
				{
					iNumberOfColumns = 4;
					sArrFields = ["hour", "minutes", "seconds", "meridiem"];
				}
				else if(oDTP.oData.bArrMatchFormat[1]) // HH:mm:ss
				{
					iNumberOfColumns = 3;
					sArrFields = ["hour", "minutes", "seconds"];
				}
				else if(oDTP.oData.bArrMatchFormat[2]) // hh:mm AA
				{
					iNumberOfColumns = 3;
					sArrFields = ["hour", "minutes", "meridiem"];
				}
				else if(oDTP.oData.bArrMatchFormat[3]) // HH:mm
				{
					iNumberOfColumns = 2;
					sArrFields = ["hour", "minutes"];
				}
			}
			// 时间显示格式为日期加时分秒类型;
			else if(oDTP.oData.bDateTimeMode)
			{
				sTitleContent = oDTP.settings.titleContentDateTime;

				if(oDTP.oData.bArrMatchFormat[0])
				{
					iNumberOfColumns = 6;
					sArrFields = ["day", "month", "year", "hour", "minutes", "seconds"];
				}
				else if(oDTP.oData.bArrMatchFormat[1])
				{
					iNumberOfColumns = 7;
					sArrFields = ["day", "month", "year", "hour", "minutes", "seconds", "meridiem"];
				}
				else if(oDTP.oData.bArrMatchFormat[2])
				{
					iNumberOfColumns = 6;
					sArrFields = ["month", "day", "year", "hour", "minutes", "seconds"];
				}
				else if(oDTP.oData.bArrMatchFormat[3])
				{
					iNumberOfColumns = 7;
					sArrFields = ["month", "day", "year", "hour", "minutes", "seconds", "meridiem"];
				}
				else if(oDTP.oData.bArrMatchFormat[4])
				{
					iNumberOfColumns = 6;
					sArrFields = ["year", "month", "day", "hour", "minutes", "seconds"];
				}
				else if(oDTP.oData.bArrMatchFormat[5])
				{
					iNumberOfColumns = 7;
					sArrFields = ["year", "month", "day", "hour", "minutes", "seconds", "meridiem"];
				}
				else if(oDTP.oData.bArrMatchFormat[6])
				{
					iNumberOfColumns = 6;
					sArrFields = ["day", "month", "year", "hour", "minutes", "seconds"];
				}
				else if(oDTP.oData.bArrMatchFormat[7])
				{
					iNumberOfColumns = 7;
					sArrFields = ["day", "month", "year", "hour", "minutes", "seconds", "meridiem"];
				}
				else if(oDTP.oData.bArrMatchFormat[8])
				{
					iNumberOfColumns = 5;
					sArrFields = ["day", "month", "year", "hour", "minutes"];
				}
				else if(oDTP.oData.bArrMatchFormat[9])
				{
					iNumberOfColumns = 6;
					sArrFields = ["day", "month", "year", "hour", "minutes", "meridiem"];
				}
				else if(oDTP.oData.bArrMatchFormat[10])
				{
					iNumberOfColumns = 5;
					sArrFields = ["month", "day", "year", "hour", "minutes"];
				}
				else if(oDTP.oData.bArrMatchFormat[11])
				{
					iNumberOfColumns = 6;
					sArrFields = ["month", "day", "year", "hour", "minutes", "meridiem"];
				}
				else if(oDTP.oData.bArrMatchFormat[12])
				{
					iNumberOfColumns = 5;
					sArrFields = ["year", "month", "day", "hour", "minutes"];
				}
				else if(oDTP.oData.bArrMatchFormat[13])
				{
					iNumberOfColumns = 6;
					sArrFields = ["year", "month", "day", "hour", "minutes", "meridiem"];
				}
				else if(oDTP.oData.bArrMatchFormat[14])
				{
					iNumberOfColumns = 5;
					sArrFields = ["day", "month", "year", "hour", "minutes"];
				}
				else if(oDTP.oData.bArrMatchFormat[15])
				{
					iNumberOfColumns = 6;
					sArrFields = ["day", "month", "year", "hour", "minutes", "meridiem"];
				}
			}

			var sColumnClass = "dtpicker-comp" + iNumberOfColumns,
			bDisplayHeaderCloseButton = false,
			bDisplaySetButton = false,
			bDisplayClearButton = false,
			iTempIndex;

			for(iTempIndex = 0; iTempIndex < oDTP.settings.buttonsToDisplay.length; iTempIndex++)
			{
				if($.cf._compare(oDTP.settings.buttonsToDisplay[iTempIndex], "HeaderCloseButton"))
					bDisplayHeaderCloseButton = true;
				else if($.cf._compare(oDTP.settings.buttonsToDisplay[iTempIndex], "SetButton"))
					bDisplaySetButton = true;
				else if($.cf._compare(oDTP.settings.buttonsToDisplay[iTempIndex], "ClearButton"))
					bDisplayClearButton = true;
			}

			var sHeader = "";
			sHeader += "<div class='dtpicker-header'>";
			sHeader += "<div class='dtpicker-title'>" + sTitleContent + "</div>";
			if(bDisplayHeaderCloseButton)
				sHeader += "<a class='dtpicker-close'>&times;</a>";
			sHeader += "<div class='dtpicker-value'></div>";
			sHeader += "</div>";

			var sDTPickerComp = "";
			sDTPickerComp += "<div class='dtpicker-components'>";

			for(iTempIndex = 0; iTempIndex < iNumberOfColumns; iTempIndex++)
			{
				var sFieldName = sArrFields[iTempIndex];

				sDTPickerComp += "<div class='dtpicker-compOutline " + sColumnClass + "'>";
				sDTPickerComp += "<div class='dtpicker-comp " + sFieldName + "'>";
				sDTPickerComp += "<a class='dtpicker-compButton increment'>" + oDTP.settings.incrementButtonContent + "</a>";
				sDTPickerComp += "<input type='text' class='dtpicker-compValue'></input>";
				sDTPickerComp += "<a class='dtpicker-compButton decrement'>" + oDTP.settings.decrementButtonContent + "</a>";
				if(oDTP.settings.labels)
					sDTPickerComp += "<div class='dtpicker-label'>" + oDTP.settings.labels[sFieldName] + "</div>";
				sDTPickerComp += "</div>";
				sDTPickerComp += "</div>";
			}

			sDTPickerComp += "</div>";

			var sButtonContClass = "";
			if(bDisplaySetButton && bDisplayClearButton)
				sButtonContClass = " dtpicker-twoButtons";
			else
				sButtonContClass = " dtpicker-singleButton";

			var sDTPickerButtons = "";
			sDTPickerButtons += "<div class='dtpicker-buttonCont" + sButtonContClass + "'>";
			if(bDisplaySetButton)
				sDTPickerButtons += "<a class='dtpicker-button dtpicker-buttonSet'>" + oDTP.settings.setButtonContent + "</a>";
			if(bDisplayClearButton)
				sDTPickerButtons += "<a class='dtpicker-button dtpicker-buttonClear'>" + oDTP.settings.clearButtonContent + "</a>";
			sDTPickerButtons += "</div>";

			var sTempStr = sHeader + sDTPickerComp + sDTPickerButtons;

			$(oDTP.element).find('.dtpicker-subcontent').html(sTempStr);

			// 获取时间面板显示日期并填充,设置时间面板的时间标题;设置+、-按钮是否可点击;
			oDTP._setCurrentDate();

			oDTP._addEventHandlersForPicker();
		},

		// 时间面板绑定事件
		_addEventHandlersForPicker: function()
		{
			var oDTP = this;

			$(document).on("click.DateTimePicker", function(e)
			{
				oDTP._hidePicker("");
			});

			$(document).on("keydown.DateTimePicker", function(e)
			{
				// $('.dtpicker-compValue')事件面板中各时间输入框
				if(! $('.dtpicker-compValue').is(':focus') && parseInt(e.keyCode ? e.keyCode : e.which) === 9)
				{
					oDTP._setButtonAction(true);
					// tabIndex属性的意义???
					$("[tabIndex=" + (oDTP.oData.iTabIndex + 1) + "]").focus();
					return false;
				}
			});

			$(document).on("keydown.DateTimePicker", function(e)
			{
				if(! $('.dtpicker-compValue').is(':focus') && parseInt(e.keyCode ? e.keyCode : e.which) !== 9)
				{
					oDTP._hidePicker("");
				}
			});

			// 阻止事件向上传播,因此时间面板被点击时不会触发document绑定的隐藏事件
			$(".dtpicker-cont *").click(function(e)
			{
				e.stopPropagation();
			});

			$('.dtpicker-compValue').not('.month .dtpicker-compValue, .meridiem .dtpicker-compValue').keyup(function()
			{
				this.value = this.value.replace(/[^0-9\.]/g,'');
			});

			$('.dtpicker-compValue').focus(function()
			{
				oDTP.oData.bElemFocused = true;
				$(this).select();
			});

			// 时间面板上输入框失去焦点调整各显示时间,最后一个元素隐藏面板
			$('.dtpicker-compValue').blur(function()
			{
				oDTP._getValuesFromInputBoxes();
				oDTP._setCurrentDate();

				oDTP.oData.bElemFocused = false;
				var $oParentElem = $(this).parent().parent();
				setTimeout(function()
				{
					if($oParentElem.is(':last-child') && !oDTP.oData.bElemFocused)
					{
						oDTP._setButtonAction(false);
					}
				}, 50);
			});

			// 调整时间面板上的输入值,比如日期截取前两位等
			$(".dtpicker-compValue").keyup(function(e)
			{
				var $oTextField = $(this),

				sTextBoxVal = $oTextField.val(),
				iLength = sTextBoxVal.length,
				sNewTextBoxVal;

				if($oTextField.parent().hasClass("day") || $oTextField.parent().hasClass("hour") || $oTextField.parent().hasClass("minutes") || $oTextField.parent().hasClass("meridiem"))
				{
					if(iLength > 2)
					{
						sNewTextBoxVal = sTextBoxVal.slice(0, 2);
						$oTextField.val(sNewTextBoxVal);
					}
				}
				else if($oTextField.parent().hasClass("month"))
				{
					if(iLength > 3)
					{
						sNewTextBoxVal = sTextBoxVal.slice(0, 3);
						$oTextField.val(sNewTextBoxVal);
					}
				}
				else if($oTextField.parent().hasClass("year"))
				{
					if(iLength > 4)
					{
						sNewTextBoxVal = sTextBoxVal.slice(0, 4);
						$oTextField.val(sNewTextBoxVal);
					}
				}

				if(parseInt(e.keyCode ? e.keyCode : e.which) === 9)
					$(this).select();
			});

			// 各按钮事件
			$(oDTP.element).find('.dtpicker-close').click(function(e)
			{
				if(oDTP.settings.buttonClicked)
					oDTP.settings.buttonClicked.call(oDTP, "CLOSE", oDTP.oData.oInputElement);
				oDTP._hidePicker("");
			});

			$(oDTP.element).find('.dtpicker-buttonSet').click(function(e)
			{
				if(oDTP.settings.buttonClicked)
					oDTP.settings.buttonClicked.call(oDTP, "SET", oDTP.oData.oInputElement);
				oDTP._setButtonAction(false);
			});

			$(oDTP.element).find('.dtpicker-buttonClear').click(function(e)
			{
				if(oDTP.settings.buttonClicked)
					oDTP.settings.buttonClicked.call(oDTP, "CLEAR", oDTP.oData.oInputElement);
				oDTP._clearButtonAction();
			});

			// 绑定+、-按钮的点击事件,以及AM、PM切换
			$(oDTP.element).find(".day .increment, .day .increment *").click(function(e)
			{
				oDTP.oData.iCurrentDay++;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".day .decrement, .day .decrement *").click(function(e)
			{
				oDTP.oData.iCurrentDay--;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".month .increment, .month .increment *").click(function(e)
			{
				oDTP.oData.iCurrentMonth++;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".month .decrement, .month .decrement *").click(function(e)
			{
				oDTP.oData.iCurrentMonth--;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".year .increment, .year .increment *").click(function(e)
			{
				oDTP.oData.iCurrentYear++;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".year .decrement, .year .decrement *").click(function(e)
			{
				oDTP.oData.iCurrentYear--;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".hour .increment, .hour .increment *").click(function(e)
			{
				oDTP.oData.iCurrentHour++;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".hour .decrement, .hour .decrement *").click(function(e)
			{
				oDTP.oData.iCurrentHour--;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".minutes .increment, .minutes .increment *").click(function(e)
			{
				oDTP.oData.iCurrentMinutes += oDTP.settings.minuteInterval;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".minutes .decrement, .minutes .decrement *").click(function(e)
			{
				oDTP.oData.iCurrentMinutes -= oDTP.settings.minuteInterval;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".seconds .increment, .seconds .increment *").click(function(e)
			{
				oDTP.oData.iCurrentSeconds += oDTP.settings.secondsInterval;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".seconds .decrement, .seconds .decrement *").click(function(e)
			{
				oDTP.oData.iCurrentSeconds -= oDTP.settings.secondsInterval;
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});

			$(oDTP.element).find(".meridiem .dtpicker-compButton, .meridiem .dtpicker-compButton *").click(function(e)
			{
				if($.cf._compare(oDTP.oData.sCurrentMeridiem, "AM"))
				{
					oDTP.oData.sCurrentMeridiem = "PM";
					oDTP.oData.iCurrentHour += 12;
				}
				else if($.cf._compare(oDTP.oData.sCurrentMeridiem, "PM"))
				{
					oDTP.oData.sCurrentMeridiem = "AM";
					oDTP.oData.iCurrentHour -= 12;
				}
				oDTP._setCurrentDate();
				oDTP._setOutputOnIncrementOrDecrement();
			});
		},

		// 以特定步长调整分秒显示
		_adjustMinutes: function(iMinutes)
		{
			var oDTP = this;
			if(oDTP.settings.roundOffMinutes && oDTP.settings.minuteInterval !== 1)
			{
				iMinutes = (iMinutes % oDTP.settings.minuteInterval) ? (iMinutes - (iMinutes % oDTP.settings.minuteInterval) + oDTP.settings.minuteInterval) : iMinutes;
			}
			return iMinutes;
		},

		_adjustSeconds: function(iSeconds)
		{
			var oDTP = this;
			if(oDTP.settings.roundOffSeconds && oDTP.settings.secondsInterval !== 1)
			{
				iSeconds = (iSeconds % oDTP.settings.secondsInterval) ? (iSeconds - (iSeconds % oDTP.settings.secondsInterval) + oDTP.settings.secondsInterval) : iSeconds;
			}
			return iSeconds;
		},

		// 获取元素的html或val值
		_getValueOfElement: function(oElem)
		{
			var oDTP = this;
			var sElemValue = "";

			if($.cf._compare($(oElem).prop("tagName"), "INPUT"))
				sElemValue = $(oElem).val();
			else
				sElemValue = $(oElem).html();

			return sElemValue;
		},

		// 将时间输出填充到输入框或指定的Dom元素中
		_setValueOfElement: function(sElemValue, $oElem)
		{
			var oDTP = this;

			if(!$.cf._isValid($oElem))
				$oElem = $(oDTP.oData.oInputElement);

			if($.cf._compare($oElem.prop("tagName"), "INPUT"))
				$oElem.val(sElemValue);
			else
				$oElem.html(sElemValue);

			var dElemValue = oDTP.getDateObjectForInputField($oElem);

			if(oDTP.settings.settingValueOfElement)
				oDTP.settings.settingValueOfElement.call(oDTP, sElemValue, dElemValue, $oElem);

			$oElem.change();// on("change",fn)同时顺利执行fn;

			return sElemValue;
		},

		//-----------------------------------------------------------------

		// 将格式化后的时间数值转化成对象形式
		_parseDate: function(sDate)
		{
			var oDTP = this;

			var dTempDate = (oDTP.settings.defaultDate ? new Date(oDTP.settings.defaultDate) : new Date()),
			iDate = dTempDate.getDate(),
			iMonth = dTempDate.getMonth(),
			iYear = dTempDate.getFullYear();

			if($.cf._isValid(sDate))
			{
				var sArrDate;
				if(oDTP.oData.bArrMatchFormat[4] || oDTP.oData.bArrMatchFormat[5] || oDTP.oData.bArrMatchFormat[6])
					sArrDate = sDate.split(oDTP.settings.monthYearSeparator);
				else
					sArrDate = sDate.split(oDTP.settings.dateSeparator);

				if(oDTP.oData.bArrMatchFormat[0])  // "dd-MM-yyyy"
				{
					iDate = parseInt(sArrDate[0]);
					iMonth = parseInt(sArrDate[1] - 1);
					iYear = parseInt(sArrDate[2]);
				}
				else if(oDTP.oData.bArrMatchFormat[1])  // "MM-dd-yyyy"
				{
					iMonth = parseInt(sArrDate[0] - 1);
					iDate = parseInt(sArrDate[1]);
					iYear = parseInt(sArrDate[2]);
				}
				else if(oDTP.oData.bArrMatchFormat[2])  // "yyyy-MM-dd"
				{
					iYear = parseInt(sArrDate[0]);
					iMonth = parseInt(sArrDate[1] - 1);
					iDate = parseInt(sArrDate[2]);
				}
				else if(oDTP.oData.bArrMatchFormat[3])  // "dd-MMM-yyyy"
				{
					iDate = parseInt(sArrDate[0]);
					iMonth = oDTP._getShortMonthIndex(sArrDate[1]);
					iYear = parseInt(sArrDate[2]);
				}
				else if(oDTP.oData.bArrMatchFormat[4])  // "MM-yyyy"
				{
					iDate = 1;
					iMonth = parseInt(sArrDate[0]) - 1;
					iYear = parseInt(sArrDate[1]);
				}
				else if(oDTP.oData.bArrMatchFormat[5])  // "MMM yyyy"
				{
					iDate = 1;
					iMonth = oDTP._getShortMonthIndex(sArrDate[0]);
					iYear = parseInt(sArrDate[1]);
				}
				else if(oDTP.oData.bArrMatchFormat[6])  // "MMMM yyyy"
				{
					iDate = 1;
					iMonth = oDTP._getFullMonthIndex(sArrDate[0]);
					iYear = parseInt(sArrDate[1]);
				}
			}

			dTempDate = new Date(iYear, iMonth, iDate, 0, 0, 0, 0);
			return dTempDate;
		},

		_parseTime: function(sTime)
		{
			var oDTP = this;

			var dTempDate = (oDTP.settings.defaultDate ? new Date(oDTP.settings.defaultDate) : new Date()),
			iDate = dTempDate.getDate(),
			iMonth = dTempDate.getMonth(),
			iYear = dTempDate.getFullYear(),
			iHour = dTempDate.getHours(),
			iMinutes = dTempDate.getMinutes(),
			iSeconds = dTempDate.getSeconds(),
			sArrTime, sMeridiem, sArrTimeComp,
			bShowSeconds = oDTP.oData.bArrMatchFormat[0] ||
							oDTP.oData.bArrMatchFormat[1];

			iSeconds = bShowSeconds ? oDTP._adjustSeconds(iSeconds) : 0;

			if($.cf._isValid(sTime))
			{
				if(oDTP.oData.bIs12Hour)
				{
					sArrTime = sTime.split(oDTP.settings.timeMeridiemSeparator);
					sTime = sArrTime[0];
					sMeridiem = sArrTime[1];

					if(!($.cf._compare(sMeridiem, "AM") || $.cf._compare(sMeridiem, "PM")))
						sMeridiem = "";
				}

				sArrTimeComp = sTime.split(oDTP.settings.timeSeparator);
				iHour = parseInt(sArrTimeComp[0]);
				iMinutes = parseInt(sArrTimeComp[1]);

				if(bShowSeconds)
				{
					iSeconds = parseInt(sArrTimeComp[2]);
					iSeconds = oDTP._adjustSeconds(iSeconds);
				}

				if(iHour === 12 && $.cf._compare(sMeridiem, "AM"))
					iHour = 0;
				else if(iHour < 12 && $.cf._compare(sMeridiem, "PM"))
					iHour += 12;
			}
			iMinutes = oDTP._adjustMinutes(iMinutes);

			dTempDate = new Date(iYear, iMonth, iDate, iHour, iMinutes, iSeconds, 0);

			return dTempDate;
		},

		_parseDateTime: function(sDateTime)
		{
			var oDTP = this;

			var dTempDate = (oDTP.settings.defaultDate ? new Date(oDTP.settings.defaultDate) : new Date()),
			iDate = dTempDate.getDate(),
			iMonth = dTempDate.getMonth(),
			iYear = dTempDate.getFullYear(),
			iHour = dTempDate.getHours(),
			iMinutes = dTempDate.getMinutes(),
			iSeconds = dTempDate.getSeconds(),
			sMeridiem = "",
			sArrDateTime, sArrDate, sTime, sArrTimeComp, sArrTime,
			bShowSeconds = oDTP.oData.bArrMatchFormat[0] || // "dd-MM-yyyy HH:mm:ss"
							oDTP.oData.bArrMatchFormat[1] || // ""dd-MM-yyyy hh:mm:ss AA"
							oDTP.oData.bArrMatchFormat[2] || // "MM-dd-yyyy HH:mm:ss"
							oDTP.oData.bArrMatchFormat[3] || // "MM-dd-yyyy hh:mm:ss AA"
							oDTP.oData.bArrMatchFormat[4] || // "yyyy-MM-dd HH:mm:ss"
							oDTP.oData.bArrMatchFormat[5] || // "yyyy-MM-dd hh:mm:ss AA"
							oDTP.oData.bArrMatchFormat[6] || // "dd-MMM-yyyy HH:mm:ss"
							oDTP.oData.bArrMatchFormat[7]; // "dd-MMM-yyyy hh:mm:ss AA"

			iSeconds = bShowSeconds ? oDTP._adjustSeconds(iSeconds) : 0;

			if($.cf._isValid(sDateTime))
			{
				sArrDateTime = sDateTime.split(oDTP.settings.dateTimeSeparator);
				sArrDate = sArrDateTime[0].split(oDTP.settings.dateSeparator);

				if(oDTP.oData.bArrMatchFormat[0] || // "dd-MM-yyyy HH:mm:ss"
					oDTP.oData.bArrMatchFormat[1] || // ""dd-MM-yyyy hh:mm:ss AA"
					oDTP.oData.bArrMatchFormat[8] || // "dd-MM-yyyy HH:mm"
					oDTP.oData.bArrMatchFormat[9]) // "dd-MM-yyyy hh:mm AA"
				{
					iDate = parseInt(sArrDate[0]);
					iMonth = parseInt(sArrDate[1] - 1);
					iYear = parseInt(sArrDate[2]);
				}
				else if(oDTP.oData.bArrMatchFormat[2] ||  // "MM-dd-yyyy HH:mm:ss"
					oDTP.oData.bArrMatchFormat[3] || // "MM-dd-yyyy hh:mm:ss AA"
					oDTP.oData.bArrMatchFormat[10] ||  // "MM-dd-yyyy HH:mm"
					oDTP.oData.bArrMatchFormat[11]) // "MM-dd-yyyy hh:mm AA"
				{
					iMonth = parseInt(sArrDate[0] - 1);
					iDate = parseInt(sArrDate[1]);
					iYear = parseInt(sArrDate[2]);
				}
				else if(oDTP.oData.bArrMatchFormat[4] ||  // "yyyy-MM-dd HH:mm:ss"
					oDTP.oData.bArrMatchFormat[5] || // "yyyy-MM-dd hh:mm:ss AA"
					oDTP.oData.bArrMatchFormat[12] ||  // "yyyy-MM-dd HH:mm"
					oDTP.oData.bArrMatchFormat[13]) // "yyyy-MM-dd hh:mm AA"
				{
					iYear = parseInt(sArrDate[0]);
					iMonth = parseInt(sArrDate[1] - 1);
					iDate = parseInt(sArrDate[2]);
				}
				else if(oDTP.oData.bArrMatchFormat[6] || // "dd-MMM-yyyy HH:mm:ss"
					oDTP.oData.bArrMatchFormat[7] || // "dd-MMM-yyyy hh:mm:ss AA"
					oDTP.oData.bArrMatchFormat[14] || // "dd-MMM-yyyy HH:mm:ss"
					oDTP.oData.bArrMatchFormat[15]) // "dd-MMM-yyyy hh:mm:ss AA"
				{
					iDate = parseInt(sArrDate[0]);
					iMonth = oDTP._getShortMonthIndex(sArrDate[1]);
					iYear = parseInt(sArrDate[2]);
				}

				sTime = sArrDateTime[1];
				if($.cf._isValid(sTime))
				{
					if(oDTP.oData.bIs12Hour)
					{
						if($.cf._compare(oDTP.settings.dateTimeSeparator, oDTP.settings.timeMeridiemSeparator) && (sArrDateTime.length === 3))
							sMeridiem = sArrDateTime[2];
						else
						{
							sArrTimeComp = sTime.split(oDTP.settings.timeMeridiemSeparator);
							sTime = sArrTimeComp[0];
							sMeridiem = sArrTimeComp[1];
						}

						if(!($.cf._compare(sMeridiem, "AM") || $.cf._compare(sMeridiem, "PM")))
							sMeridiem = "";
					}

					sArrTime = sTime.split(oDTP.settings.timeSeparator);

					iHour = parseInt(sArrTime[0]);
					iMinutes = parseInt(sArrTime[1]);
					if(bShowSeconds)
					{
						iSeconds = parseInt(sArrTime[2]);
					}

					if(iHour === 12 && $.cf._compare(sMeridiem, "AM"))
						iHour = 0;
					else if(iHour < 12 && $.cf._compare(sMeridiem, "PM"))
						iHour += 12;
				}
			}
			iMinutes = oDTP._adjustMinutes(iMinutes);

			dTempDate = new Date(iYear, iMonth, iDate, iHour, iMinutes, iSeconds, 0);
			return dTempDate;
		},

		// 返回月份全写、简写形式的index值
		_getShortMonthIndex: function(sMonthName)
		{
			var oDTP = this;

			for(var iTempIndex = 0; iTempIndex < oDTP.settings.shortMonthNames.length; iTempIndex++)
			{
				if($.cf._compare(sMonthName, oDTP.settings.shortMonthNames[iTempIndex]))
					return iTempIndex;
			}
		},

		_getFullMonthIndex: function(sMonthName)
		{
			var oDTP = this;

			for(var iTempIndex = 0; iTempIndex < oDTP.settings.fullMonthNames.length; iTempIndex++)
			{
				if($.cf._compare(sMonthName, oDTP.settings.fullMonthNames[iTempIndex]))
					return iTempIndex;
			}
		},

		// 是否12小时制
		getIs12Hour: function(sMode, sFormat)
		{
			var oDTP = this;

			var bIs12Hour = false,
			iArgsLength = Function.length;

			oDTP._setMatchFormat(iArgsLength, sMode, sFormat);

			if(oDTP.oData.bTimeMode)
	        {
	        	bIs12Hour = oDTP.oData.bArrMatchFormat[0] ||
	        				oDTP.oData.bArrMatchFormat[2];
	        }
	        else if(oDTP.oData.bDateTimeMode)
	        {
	        	bIs12Hour = oDTP.oData.bArrMatchFormat[1] ||
							oDTP.oData.bArrMatchFormat[3] ||
							oDTP.oData.bArrMatchFormat[5] ||
							oDTP.oData.bArrMatchFormat[7] ||
							oDTP.oData.bArrMatchFormat[9] ||
							oDTP.oData.bArrMatchFormat[11] ||
							oDTP.oData.bArrMatchFormat[13] ||
							oDTP.oData.bArrMatchFormat[15];
			}

			oDTP._setMatchFormat(iArgsLength);

			return bIs12Hour;
		},

		//-----------------------------------------------------------------

		// 获取触发输入框的时间设置,或者创建新的时间对象(this.oData.dCurrentDate或new Date())
		// 根据bIncludeTime判断是否包含时分秒,bSetMeridiem判断12小时制或24小时制
		_setVariablesForDate: function(dInput, bIncludeTime, bSetMeridiem)
		{
			var oDTP = this;

			var dTemp, oDTV = {},
			bValidInput = $.cf._isValid(dInput);
			if(bValidInput)
			{
				dTemp = new Date(dInput);
				if(!$.cf._isValid(bIncludeTime))
					bIncludeTime = true;
				if(!$.cf._isValid(bSetMeridiem))
					bSetMeridiem = true;
			}
			else
			{
				if (Object.prototype.toString.call(oDTP.oData.dCurrentDate) === '[object Date]' && isFinite(oDTP.oData.dCurrentDate))
    		  			dTemp = new Date(oDTP.oData.dCurrentDate);
  				else
    					dTemp = new Date();

				if(!$.cf._isValid(bIncludeTime))
					// 实际上并不需要传值判断bIncludeTime是否有效
					// 直接判断oDTP.oData.bTimeMode、oDTP.oData.bDateTimeMode是否为真就好
					// 触发输入框有值时的情况也相同※※※
					bIncludeTime = (oDTP.oData.bTimeMode || oDTP.oData.bDateTimeMode);
				if(!$.cf._isValid(bSetMeridiem))
					bSetMeridiem = oDTP.oData.bIs12Hour;
			}

			// 触发元素输入框有值时,先赋值给oData.dCurrentDate,再赋值给oDTV.iCurrentDay;
			// 触发元素输入框无值时,取当前时间的日期对象赋值给oDTV.iCurrentDay;
			oDTV.iCurrentDay = dTemp.getDate();
			oDTV.iCurrentMonth = dTemp.getMonth();
			oDTV.iCurrentYear = dTemp.getFullYear();
			oDTV.iCurrentWeekday = dTemp.getDay();

			if(bIncludeTime)
			{
				oDTV.iCurrentHour = dTemp.getHours();
				oDTV.iCurrentMinutes = dTemp.getMinutes();
				oDTV.iCurrentSeconds = dTemp.getSeconds();

				if(bSetMeridiem)
				{
					oDTV.sCurrentMeridiem = oDTP._determineMeridiemFromHourAndMinutes(oDTV.iCurrentHour, oDTV.iCurrentMinutes);
				}
			}

			// dInput有效时,将dInput的值转化为日期对象后返回;
			// 无效时,获取输入框的初始时间或当前时间转化为日期对象赋值给this.oData.icurrentDay;
			if(bValidInput)
				return oDTV;
			else
				oDTP.oData = $.extend(oDTP.oData, oDTV);
		},

		// 获取时间面板各列年月日时分秒的值,更新this.oData.iCurrentYear等
		_getValuesFromInputBoxes: function()
		{
			var oDTP = this;

			if(oDTP.oData.bDateMode || oDTP.oData.bDateTimeMode)
			{
				var sMonth, iMonth;

				sMonth = $(oDTP.element).find(".month .dtpicker-compValue").val();
				if(sMonth.length > 1)
					sMonth = sMonth.charAt(0).toUpperCase() + sMonth.slice(1);
				iMonth = oDTP.settings.shortMonthNames.indexOf(sMonth);
				if(iMonth !== -1)
				{
					oDTP.oData.iCurrentMonth = parseInt(iMonth);
				}
				else
				{
					if(sMonth.match("^[+|-]?[0-9]+$"))
					{
						oDTP.oData.iCurrentMonth = parseInt(sMonth - 1);
					}
				}

				oDTP.oData.iCurrentDay = parseInt($(oDTP.element).find(".day .dtpicker-compValue").val()) || oDTP.oData.iCurrentDay;
				oDTP.oData.iCurrentYear = parseInt($(oDTP.element).find(".year .dtpicker-compValue").val()) || oDTP.oData.iCurrentYear;
			}

			if(oDTP.oData.bTimeMode || oDTP.oData.bDateTimeMode)
			{
				var iTempHour, iTempMinutes, iTempSeconds, sMeridiem;

				iTempHour = parseInt($(oDTP.element).find(".hour .dtpicker-compValue").val());
				iTempMinutes = oDTP._adjustMinutes(parseInt($(oDTP.element).find(".minutes .dtpicker-compValue").val()));
				iTempSeconds = oDTP._adjustMinutes(parseInt($(oDTP.element).find(".seconds .dtpicker-compValue").val()));

				oDTP.oData.iCurrentHour = isNaN(iTempHour) ? oDTP.oData.iCurrentHour : iTempHour;
				oDTP.oData.iCurrentMinutes = isNaN(iTempMinutes) ? oDTP.oData.iCurrentMinutes : iTempMinutes;
				oDTP.oData.iCurrentSeconds = isNaN(iTempSeconds) ? oDTP.oData.iCurrentSeconds : iTempSeconds;

				if(oDTP.oData.iCurrentSeconds > 59)
				{
					oDTP.oData.iCurrentMinutes += oDTP.oData.iCurrentSeconds / 60;
					oDTP.oData.iCurrentSeconds = oDTP.oData.iCurrentSeconds % 60;
				}
				if(oDTP.oData.iCurrentMinutes > 59)
				{
					oDTP.oData.iCurrentHour += oDTP.oData.iCurrentMinutes / 60;
					oDTP.oData.iCurrentMinutes = oDTP.oData.iCurrentMinutes % 60;
				}

				if(oDTP.oData.bIs12Hour)
				{
					if(oDTP.oData.iCurrentHour > 12)
						oDTP.oData.iCurrentHour = (oDTP.oData.iCurrentHour % 12);
				}
				else
				{
					if(oDTP.oData.iCurrentHour > 23)
						oDTP.oData.iCurrentHour = (oDTP.oData.iCurrentHour % 23);
				}

				if(oDTP.oData.bIs12Hour)
				{
					sMeridiem = $(oDTP.element).find(".meridiem .dtpicker-compValue").val();
					if($.cf._compare(sMeridiem, "AM") || $.cf._compare(sMeridiem, "PM"))
						oDTP.oData.sCurrentMeridiem = sMeridiem;

					if($.cf._compare(oDTP.oData.sCurrentMeridiem, "PM"))
					{
						if(oDTP.oData.iCurrentHour !== 12 && oDTP.oData.iCurrentHour < 13)
							oDTP.oData.iCurrentHour += 12;
					}
					if($.cf._compare(oDTP.oData.sCurrentMeridiem, "AM") && oDTP.oData.iCurrentHour === 12)
						oDTP.oData.iCurrentHour = 0;
				}
			}
		},

		// 获取时间面板显示日期并填充,设置时间面板的时间标题
		// 调用_setButtons方法设置+、-按钮样式,disable为不可点击
		_setCurrentDate: function()
		{
			var oDTP = this;

			// 配合时间的秒指标以及+、-按钮调整当前秒数,以特定步长调整分秒显示;
			if(oDTP.oData.bTimeMode || oDTP.oData.bDateTimeMode)
			{
				if(oDTP.oData.iCurrentSeconds > 59)
				{
					oDTP.oData.iCurrentMinutes += oDTP.oData.iCurrentSeconds / 60;
					oDTP.oData.iCurrentSeconds = oDTP.oData.iCurrentSeconds % 60;
				}
				else if(oDTP.oData.iCurrentSeconds < 0)
				{
					oDTP.oData.iCurrentMinutes -= oDTP.settings.minuteInterval;
					oDTP.oData.iCurrentSeconds += 60;
				}
				// 以特定步长调整分秒显示;
				oDTP.oData.iCurrentMinutes = oDTP._adjustMinutes(oDTP.oData.iCurrentMinutes);
				oDTP.oData.iCurrentSeconds = oDTP._adjustSeconds(oDTP.oData.iCurrentSeconds);
			}

			// this.oData.iCurrentYear存储输入框初始时间设定或当前日期对象;
			// this.oData.dCurrentDate输入框初始时间设定;
			var dTempDate = new Date(oDTP.oData.iCurrentYear, oDTP.oData.iCurrentMonth, oDTP.oData.iCurrentDay, oDTP.oData.iCurrentHour, oDTP.oData.iCurrentMinutes, oDTP.oData.iCurrentSeconds, 0),
			bGTMaxDate = false, bLTMinDate = false,
			sFormat, oDate, oFormattedDate, oFormattedTime,
			sDate, sTime, sDateTime;

			if(oDTP.oData.dMaxValue !== null)
				bGTMaxDate = (dTempDate.getTime() > oDTP.oData.dMaxValue.getTime());
			if(oDTP.oData.dMinValue !== null)
				bLTMinDate = (dTempDate.getTime() < oDTP.oData.dMinValue.getTime());

			// 当this.oData.iCurrentYear输入框初始时间设定或当前时间不在时间范围内时;
			if(bGTMaxDate || bLTMinDate)
			{
				var bCDGTMaxDate = false, bCDLTMinDate = false;
				if(oDTP.oData.dMaxValue !== null)
					bCDGTMaxDate = (oDTP.oData.dCurrentDate.getTime() > oDTP.oData.dMaxValue.getTime());
				if(oDTP.oData.dMinValue !== null)
					bCDLTMinDate = (oDTP.oData.dCurrentDate.getTime() < oDTP.oData.dMinValue.getTime());

				// 当this.oData.dCurrentDate在时间范围内;
				if(!(bCDGTMaxDate || bCDLTMinDate))
					dTempDate = new Date(oDTP.oData.dCurrentDate);
				else
				{
					if(bCDGTMaxDate)
					{
						dTempDate = new Date(oDTP.oData.dMaxValue);
						console.log("Info : Date/Time/DateTime you entered is later than Maximum value, so DateTimePicker is showing Maximum value in Input Field.");
					}
					if(bCDLTMinDate)
					{
						dTempDate = new Date(oDTP.oData.dMinValue);
						console.log("Info : Date/Time/DateTime you entered is earlier than Minimum value, so DateTimePicker is showing Minimum value in Input Field.");
					}
					console.log("Please enter proper Date/Time/DateTime values.");
				}
			}

			// 当输入框初始设定不在最大最小时间范围内,this.oData.dCurrentDate记为最大或最小时间;
			oDTP.oData.dCurrentDate = new Date(dTempDate);
			// 更新iCurrentDay值与当前的this.oData.dCurrentDate匹配;
			oDTP._setVariablesForDate();

			oDate = {}; sDate = ""; sTime = ""; sDateTime = "";

			if(oDTP.oData.bDateMode || oDTP.oData.bDateTimeMode)
			{
				if(oDTP.oData.bDateMode && (oDTP.oData.bArrMatchFormat[4] || oDTP.oData.bArrMatchFormat[5] || oDTP.oData.bArrMatchFormat[6]))
					oDTP.oData.iCurrentDay = 1;

				oFormattedDate = oDTP._formatDate();

				// 时间格式为iCurrentDay为"MM-yyyy"时,时间面板的日期显示为1号;
				$(oDTP.element).find('.day .dtpicker-compValue').val(oFormattedDate.dd);

				// "MM-yyyy"时间格式下月份显示为数字,"MMMM yyyy"格式下显示July等,其余情况其余显示为Jul;
				if(oDTP.oData.bDateMode)
				{
					if(oDTP.oData.bArrMatchFormat[4])  // "MM-yyyy"
						$(oDTP.element).find('.month .dtpicker-compValue').val(oFormattedDate.MM);
					else if(oDTP.oData.bArrMatchFormat[6])  // "MMMM yyyy"
						$(oDTP.element).find('.month .dtpicker-compValue').val(oFormattedDate.month);
					else
						$(oDTP.element).find('.month .dtpicker-compValue').val(oFormattedDate.monthShort);
				}
				else
					$(oDTP.element).find('.month .dtpicker-compValue').val(oFormattedDate.monthShort);

				$(oDTP.element).find('.year .dtpicker-compValue').val(oFormattedDate.yyyy);

				// 以用户配置this.settings.formatHumanDate格式化时间标题
				if(oDTP.settings.formatHumanDate)
				{
					oDate = $.extend(oDate, oFormattedDate);
				}
				else
				{
					if(oDTP.oData.bDateMode && (oDTP.oData.bArrMatchFormat[4] || oDTP.oData.bArrMatchFormat[5] || oDTP.oData.bArrMatchFormat[6]))
					{
						if(oDTP.oData.bArrMatchFormat[4])
							sDate = oFormattedDate.MM + oDTP.settings.monthYearSeparator + oFormattedDate.yyyy;
						else if(oDTP.oData.bArrMatchFormat[5])
							sDate = oFormattedDate.monthShort + oDTP.settings.monthYearSeparator + oFormattedDate.yyyy;
						else if(oDTP.oData.bArrMatchFormat[6])
							sDate = oFormattedDate.month + oDTP.settings.monthYearSeparator + oFormattedDate.yyyy;
					}
					else
						sDate = oFormattedDate.dayShort + ", " + oFormattedDate.month + " " + oFormattedDate.dd + ", " + oFormattedDate.yyyy;
				}
			}
			if(oDTP.oData.bTimeMode || oDTP.oData.bDateTimeMode)
			{
				oFormattedTime = oDTP._formatTime();

				if(oDTP.oData.bIs12Hour)
					$(oDTP.element).find('.meridiem .dtpicker-compValue').val(oDTP.oData.sCurrentMeridiem);
				$(oDTP.element).find('.hour .dtpicker-compValue').val(oFormattedTime.hour);
				$(oDTP.element).find('.minutes .dtpicker-compValue').val(oFormattedTime.mm);
				$(oDTP.element).find('.seconds .dtpicker-compValue').val(oFormattedTime.ss);

				if(oDTP.settings.formatHumanDate)
				{
					oDate = $.extend(oDate, oFormattedTime);
				}
				else
				{
					var bShowSecondsTime = (oDTP.oData.bTimeMode && (
						oDTP.oData.bArrMatchFormat[0] ||
						oDTP.oData.bArrMatchFormat[1])),

					bShowSecondsDateTime = (oDTP.oData.bDateTimeMode &&
							(oDTP.oData.bArrMatchFormat[0] ||
							oDTP.oData.bArrMatchFormat[1] ||
							oDTP.oData.bArrMatchFormat[2] ||
							oDTP.oData.bArrMatchFormat[3] ||
							oDTP.oData.bArrMatchFormat[4] ||
							oDTP.oData.bArrMatchFormat[5] ||
							oDTP.oData.bArrMatchFormat[6] ||
							oDTP.oData.bArrMatchFormat[7]));

					if(bShowSecondsTime || bShowSecondsDateTime)
						sTime = oFormattedTime.hour + oDTP.settings.timeSeparator + oFormattedTime.mm + oDTP.settings.timeSeparator + oFormattedTime.ss;
					else
						sTime = oFormattedTime.hour + oDTP.settings.timeSeparator + oFormattedTime.mm;

					if(oDTP.oData.bIs12Hour)
						sTime += oDTP.settings.timeMeridiemSeparator + oDTP.oData.sCurrentMeridiem;
				}
			}

			if(oDTP.settings.formatHumanDate)
			{
				if(oDTP.oData.bDateTimeMode)
					sFormat = oDTP.oData.sDateFormat;
				else if(oDTP.oData.bDateMode)
					sFormat = oDTP.oData.sTimeFormat;
				else if(oDTP.oData.bTimeMode)
					sFormat = oDTP.oData.sDateTimeFormat;

				sDateTime = oDTP.settings.formatHumanDate.call(oDTP, oDate, oDTP.settings.mode, sFormat);
			}
			else
			{
				if(oDTP.oData.bDateTimeMode)
					sDateTime = sDate + oDTP.settings.dateTimeSeparator + sTime;
				else if(oDTP.oData.bDateMode)
					sDateTime = sDate;
				else if(oDTP.oData.bTimeMode)
					sDateTime = sTime;
			}

			$(oDTP.element).find('.dtpicker-value').html(sDateTime);

			// 当时间超过边际时,设置时间按钮不可点选
			oDTP._setButtons();
		},

		// 格式化显示时间,加"0"前缀以及计数从1开始(日期对象从0开始计数);
		// 以对象形式返回输入框初始时间或当前时间或最大最小时间(初始时间超过范围);
		_formatDate: function(oDTVP)
		{
			var oDTP = this;
			var oDTV = {},
			sDay, sYear,
			iMonth, sMonth, sMonthShort, sMonthFull,
			iDayOfTheWeek, sDayOfTheWeek, sDayOfTheWeekFull;

			if($.cf._isValid(oDTVP))
				oDTV = $.extend({}, oDTVP);
			else
			{
				oDTV.iCurrentDay = oDTP.oData.iCurrentDay;
				oDTV.iCurrentMonth = oDTP.oData.iCurrentMonth;
				oDTV.iCurrentYear = oDTP.oData.iCurrentYear;
				oDTV.iCurrentWeekday = oDTP.oData.iCurrentWeekday;
			}

			sDay = oDTV.iCurrentDay;
			sDay = (sDay < 10) ? ("0" + sDay) : sDay;
			iMonth = oDTV.iCurrentMonth;
			sMonth = oDTV.iCurrentMonth + 1;
			sMonth = (sMonth < 10) ? ("0" + sMonth) : sMonth;
			sMonthShort = oDTP.settings.shortMonthNames[iMonth];
			sMonthFull = oDTP.settings.fullMonthNames[iMonth];
			sYear = oDTV.iCurrentYear;
			iDayOfTheWeek = oDTV.iCurrentWeekday;
			sDayOfTheWeek = oDTP.settings.shortDayNames[iDayOfTheWeek];
			sDayOfTheWeekFull = oDTP.settings.fullDayNames[iDayOfTheWeek];

			return {
				"dd": sDay,
				"MM": sMonth,
				"monthShort": sMonthShort,
				"month": sMonthFull,
				"yyyy": sYear,
				"dayShort": sDayOfTheWeek,
				"day": sDayOfTheWeekFull
			};
		},

		_formatTime: function(oDTVP)
		{
			var oDTP = this;
			var oDTV = {},
			iHour24, sHour24, iHour12, sHour12, sHour,
			sMinutes, sSeconds;

			if($.cf._isValid(oDTVP))
				oDTV = $.extend({}, oDTVP);
			else
			{
				oDTV.iCurrentHour = oDTP.oData.iCurrentHour;
				oDTV.iCurrentMinutes = oDTP.oData.iCurrentMinutes;
				oDTV.iCurrentSeconds = oDTP.oData.iCurrentSeconds;
				oDTV.sCurrentMeridiem = oDTP.oData.sCurrentMeridiem;
			}

			iHour24 = oDTV.iCurrentHour;
			sHour24 = (iHour24 < 10) ? ("0" + iHour24) : iHour24;
			sHour = sHour24;

			iHour12 = oDTV.iCurrentHour;
			if(iHour12 > 12)
				iHour12 -= 12;
			if(sHour === "00")
				iHour12 = 12;
			sHour12 = (iHour12 < 10) ? ("0" + iHour12) : iHour12;
			if(oDTP.oData.bIs12Hour)
				sHour = sHour12;

			sMinutes = oDTV.iCurrentMinutes;
			sMinutes = (sMinutes < 10) ? ("0" + sMinutes) : sMinutes;
			sSeconds = oDTV.iCurrentSeconds;
			sSeconds = (sSeconds < 10) ? ("0" + sSeconds) : sSeconds;

			return {
				"H": iHour24,
				"HH": sHour24,
				"h": iHour12,
				"hh": sHour12,
				"hour": sHour,
				"m": oDTV.iCurrentMinutes,
				"mm": sMinutes,
				"s": oDTV.iCurrentSeconds,
				"ss": sSeconds,
				"ME": oDTV.sCurrentMeridiem
			};
		},

		// 当时间超过边际时,时间按钮不可点选
		_setButtons: function()
		{
			var oDTP = this;
			$(oDTP.element).find('.dtpicker-compButton').removeClass("dtpicker-compButtonDisable").addClass('dtpicker-compButtonEnable');

			var dTempDate;
			if(oDTP.oData.dMaxValue !== null)
			{
				if(oDTP.oData.bTimeMode)
				{
					// Decrement Hour
					if((oDTP.oData.iCurrentHour + 1) > oDTP.oData.dMaxValue.getHours() || ((oDTP.oData.iCurrentHour + 1) === oDTP.oData.dMaxValue.getHours() && oDTP.oData.iCurrentMinutes > oDTP.oData.dMaxValue.getMinutes()))
						$(oDTP.element).find(".hour .increment").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Decrement Minutes
					if(oDTP.oData.iCurrentHour >= oDTP.oData.dMaxValue.getHours() && (oDTP.oData.iCurrentMinutes + 1) > oDTP.oData.dMaxValue.getMinutes())
						$(oDTP.element).find(".minutes .increment").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");
				}
				else
				{
					// Increment Day
					dTempDate = new Date(oDTP.oData.iCurrentYear, oDTP.oData.iCurrentMonth, (oDTP.oData.iCurrentDay + 1), oDTP.oData.iCurrentHour, oDTP.oData.iCurrentMinutes, oDTP.oData.iCurrentSeconds, 0);
					if(dTempDate.getTime() > oDTP.oData.dMaxValue.getTime())
						$(oDTP.element).find(".day .increment").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Increment Month
					dTempDate = new Date(oDTP.oData.iCurrentYear, (oDTP.oData.iCurrentMonth + 1), oDTP.oData.iCurrentDay, oDTP.oData.iCurrentHour, oDTP.oData.iCurrentMinutes, oDTP.oData.iCurrentSeconds, 0);
					if(dTempDate.getTime() > oDTP.oData.dMaxValue.getTime())
						$(oDTP.element).find(".month .increment").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Increment Year
					dTempDate = new Date((oDTP.oData.iCurrentYear + 1), oDTP.oData.iCurrentMonth, oDTP.oData.iCurrentDay, oDTP.oData.iCurrentHour, oDTP.oData.iCurrentMinutes, oDTP.oData.iCurrentSeconds, 0);
					if(dTempDate.getTime() > oDTP.oData.dMaxValue.getTime())
						$(oDTP.element).find(".year .increment").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Increment Hour
					dTempDate = new Date(oDTP.oData.iCurrentYear, oDTP.oData.iCurrentMonth, oDTP.oData.iCurrentDay, (oDTP.oData.iCurrentHour + 1), oDTP.oData.iCurrentMinutes, oDTP.oData.iCurrentSeconds, 0);
					if(dTempDate.getTime() > oDTP.oData.dMaxValue.getTime())
						$(oDTP.element).find(".hour .increment").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Increment Minutes
					dTempDate = new Date(oDTP.oData.iCurrentYear, oDTP.oData.iCurrentMonth, oDTP.oData.iCurrentDay, oDTP.oData.iCurrentHour, (oDTP.oData.iCurrentMinutes + 1), oDTP.oData.iCurrentSeconds, 0);
					if(dTempDate.getTime() > oDTP.oData.dMaxValue.getTime())
						$(oDTP.element).find(".minutes .increment").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Increment Seconds
					dTempDate = new Date(oDTP.oData.iCurrentYear, oDTP.oData.iCurrentMonth, oDTP.oData.iCurrentDay, oDTP.oData.iCurrentHour, oDTP.oData.iCurrentMinutes, (oDTP.oData.iCurrentSeconds + 1), 0);
					if(dTempDate.getTime() > oDTP.oData.dMaxValue.getTime())
						$(oDTP.element).find(".seconds .increment").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");
				}
			}

			if(oDTP.oData.dMinValue !== null)
			{
				if(oDTP.oData.bTimeMode)
				{
					// Decrement Hour
					if((oDTP.oData.iCurrentHour - 1) < oDTP.oData.dMinValue.getHours() || ((oDTP.oData.iCurrentHour - 1) === oDTP.oData.dMinValue.getHours() && oDTP.oData.iCurrentMinutes < oDTP.oData.dMinValue.getMinutes()))
						$(oDTP.element).find(".hour .decrement").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Decrement Minutes
					if(oDTP.oData.iCurrentHour <= oDTP.oData.dMinValue.getHours() && (oDTP.oData.iCurrentMinutes - 1) < oDTP.oData.dMinValue.getMinutes())
						$(oDTP.element).find(".minutes .decrement").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");
				}
				else
				{
					// Decrement Day
					dTempDate = new Date(oDTP.oData.iCurrentYear, oDTP.oData.iCurrentMonth, (oDTP.oData.iCurrentDay - 1), oDTP.oData.iCurrentHour, oDTP.oData.iCurrentMinutes, oDTP.oData.iCurrentSeconds, 0);
					if(dTempDate.getTime() < oDTP.oData.dMinValue.getTime())
						$(oDTP.element).find(".day .decrement").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Decrement Month
					dTempDate = new Date(oDTP.oData.iCurrentYear, (oDTP.oData.iCurrentMonth - 1), oDTP.oData.iCurrentDay, oDTP.oData.iCurrentHour, oDTP.oData.iCurrentMinutes, oDTP.oData.iCurrentSeconds, 0);
					if(dTempDate.getTime() < oDTP.oData.dMinValue.getTime())
						$(oDTP.element).find(".month .decrement").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Decrement Year
					dTempDate = new Date((oDTP.oData.iCurrentYear - 1), oDTP.oData.iCurrentMonth, oDTP.oData.iCurrentDay, oDTP.oData.iCurrentHour, oDTP.oData.iCurrentMinutes, oDTP.oData.iCurrentSeconds, 0);
					if(dTempDate.getTime() < oDTP.oData.dMinValue.getTime())
						$(oDTP.element).find(".year .decrement").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Decrement Hour
					dTempDate = new Date(oDTP.oData.iCurrentYear, oDTP.oData.iCurrentMonth, oDTP.oData.iCurrentDay, (oDTP.oData.iCurrentHour - 1), oDTP.oData.iCurrentMinutes, oDTP.oData.iCurrentSeconds, 0);
					if(dTempDate.getTime() < oDTP.oData.dMinValue.getTime())
						$(oDTP.element).find(".hour .decrement").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Decrement Minutes
					dTempDate = new Date(oDTP.oData.iCurrentYear, oDTP.oData.iCurrentMonth, oDTP.oData.iCurrentDay, oDTP.oData.iCurrentHour, (oDTP.oData.iCurrentMinutes - 1), oDTP.oData.iCurrentSeconds, 0);
					if(dTempDate.getTime() < oDTP.oData.dMinValue.getTime())
						$(oDTP.element).find(".minutes .decrement").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");

					// Decrement Seconds
					dTempDate = new Date(oDTP.oData.iCurrentYear, oDTP.oData.iCurrentMonth, oDTP.oData.iCurrentDay, oDTP.oData.iCurrentHour, oDTP.oData.iCurrentMinutes, (oDTP.oData.iCurrentSeconds - 1), 0);
					if(dTempDate.getTime() < oDTP.oData.dMinValue.getTime())
						$(oDTP.element).find(".seconds .decrement").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");
				}
			}

			if(oDTP.oData.bIs12Hour)
			{
				var iTempHour, iTempMinutes;
				if(oDTP.oData.dMaxValue !== null || oDTP.oData.dMinValue !== null)
				{
					iTempHour = oDTP.oData.iCurrentHour;
					if($.cf._compare(oDTP.oData.sCurrentMeridiem, "AM"))
						iTempHour += 12;
					else if($.cf._compare(oDTP.oData.sCurrentMeridiem, "PM"))
						iTempHour -= 12;

					dTempDate = new Date(oDTP.oData.iCurrentYear, oDTP.oData.iCurrentMonth, oDTP.oData.iCurrentDay, iTempHour, oDTP.oData.iCurrentMinutes, oDTP.oData.iCurrentSeconds, 0);

					if(oDTP.oData.dMaxValue !== null)
					{
						if(oDTP.oData.bTimeMode)
						{
							iTempMinutes = oDTP.oData.iCurrentMinutes;
							if(iTempHour > oDTP.oData.dMaxValue.getHours() || (iTempHour === oDTP.oData.dMaxValue.getHours() && iTempMinutes > oDTP.oData.dMaxValue.getMinutes()))
								$(oDTP.element).find(".meridiem .dtpicker-compButton").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");
						}
						else
						{
							if(dTempDate.getTime() > oDTP.oData.dMaxValue.getTime())
								$(oDTP.element).find(".meridiem .dtpicker-compButton").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");
						}
					}

					if(oDTP.oData.dMinValue !== null)
					{
						if(oDTP.oData.bTimeMode)
						{
							iTempMinutes = oDTP.oData.iCurrentMinutes;
							if(iTempHour < oDTP.oData.dMinValue.getHours() || (iTempHour === oDTP.oData.dMinValue.getHours() && iTempMinutes < oDTP.oData.dMinValue.getMinutes()))
								$(oDTP.element).find(".meridiem .dtpicker-compButton").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");
						}
						else
						{
							if(dTempDate.getTime() < oDTP.oData.dMinValue.getTime())
								$(oDTP.element).find(".meridiem .dtpicker-compButton").removeClass("dtpicker-compButtonEnable").addClass("dtpicker-compButtonDisable");
						}
					}
				}
			}
		},

		// 日期面板弹窗或内嵌
		setIsPopup: function(bIsPopup)
		{
			var oDTP = this;
			oDTP.settings.isPopup = bIsPopup;

			if($(oDTP.element).css("display") !== "none")
				oDTP._hidePicker(0);

			if(oDTP.settings.isPopup)
			{
				$(oDTP.element).addClass("dtpicker-mobile");

				$(oDTP.element).css({position: "fixed", top: 0, left: 0, width: "100%", height: "100%"});
			}
			else
			{
				$(oDTP.element).removeClass("dtpicker-mobile");

				if(oDTP.oData.oInputElement !== null)
				{
					var iElemTop = $(oDTP.oData.oInputElement).offset().top + $(oDTP.oData.oInputElement).outerHeight(),
					iElemLeft = $(oDTP.oData.oInputElement).offset().left,
					iElemWidth =  $(oDTP.oData.oInputElement).outerWidth();

					$(oDTP.element).css({position: "absolute", top: iElemTop, left: iElemLeft, width: iElemWidth, height: "auto"});
				}
			}
		},

		// 时间比较
		_compareDates: function(dDate1, dDate2)
		{
			dDate1 = new Date(dDate1.getDate(), dDate1.getMonth(), dDate1.getFullYear(), 0, 0, 0, 0);
			dDate1 = new Date(dDate1.getDate(), dDate1.getMonth(), dDate1.getFullYear(), 0, 0, 0, 0);
			var iDateDiff = (dDate1.getTime() - dDate2.getTime()) / 864E5;
			return (iDateDiff === 0) ? iDateDiff: (iDateDiff/Math.abs(iDateDiff));
		},

		_compareTime: function(dTime1, dTime2)
		{
			var iTimeMatch = 0;
			if((dTime1.getHours() === dTime2.getHours()) && (dTime1.getMinutes() === dTime2.getMinutes()))
				iTimeMatch = 1;  	// 1 = Exact Match
			else
			{
				if(dTime1.getHours() < dTime2.getHours())
					iTimeMatch = 2;	 // time1 < time2
				else if(dTime1.getHours() > dTime2.getHours())
					iTimeMatch = 3; 	// time1 > time2
				else if(dTime1.getHours() === dTime2.getHours())
				{
					if(dTime1.getMinutes() < dTime2.getMinutes())
						iTimeMatch = 2;	 // time1 < time2
					else if(dTime1.getMinutes() > dTime2.getMinutes())
						iTimeMatch = 3; 	// time1 > time2
				}
			}
			return iTimeMatch;
		},

		_compareDateTime: function(dDate1, dDate2)
		{
			var iDateTimeDiff = (dDate1.getTime() - dDate2.getTime()) / 6E4;
			return (iDateTimeDiff === 0) ? iDateTimeDiff: (iDateTimeDiff/Math.abs(iDateTimeDiff));
		},

		// 设置12小时制或24小时制
		_determineMeridiemFromHourAndMinutes: function(iHour, iMinutes)
		{
			if(iHour > 12)
			{
				return "PM";
			}
			else if(iHour === 12 && iMinutes >= 0)
			{
				return "PM";
			}
			else
			{
				return "AM";
			}
		},

		// Public Method
		setLanguage: function(sLanguage)
		{
			var oDTP = this;

			oDTP.settings = $.extend({}, $.DateTimePicker.defaults, $.DateTimePicker.i18n[sLanguage], oDTP.options);

			oDTP._setDateFormatArray(); // Set DateFormatArray
			oDTP._setTimeFormatArray(); // Set TimeFormatArray
			oDTP._setDateTimeFormatArray(); // Set DateTimeFormatArray

			return oDTP;
		}

	};

}));

2.calendar

插件欠成熟,未能提供足够的方法和事件,对控制台提示、报错信息也没有任何处理。

/**
 * javascript日历控件
 * @author tugenhua
 */

 function Calendar(options,callback){
	var self = this;
	self.options = $.extend({},defaults,options || {});
	self.targetCls = $(self.options.targetCls);
	if(self.targetCls.length < 1) {return;}
	self.language = self.options.language;

	// 显示日历面板
	self.flag = false;

	self.callback = callback;

	self._init();
	self._bindEnv();

 };
 $.extend(Calendar.prototype,{

	_init: function(){
		var self = this;
		// 先渲染日历面板
		self._renderCalendarPanel();
	},
	_renderCalendarPanel: function(){
		var self = this,
			options = self.options;
		// 如果input输入框有日期的话
		if(self.targetCls.val().length > 0) {
			self.date = self._dateParse(self.targetCls.val());
		}
		self.date = new Date(self.date);
		if(isNaN(self.date.getFullYear())){
			self.date = new Date();
		}
		var defYear = self.date.getFullYear(),
			defMonth = self.date.getMonth() + 1;

		// 定义每月的天数
		self.month_day = new Array(31,28+self._leapYear(defYear),31,30,31,30,31,31,30,31,30,31);

		// 定义每周的日期
		self.date_name_week = self.language.weekList;

		// 定义周末
		var saturday = 6 - options.wdays,
			sunday = (7-options.wdays >= 7) ? 0 : (7-options.wday);

		// 创建日历面板dom节点
		var date_pane = $('<div class="cxcalendar"></div>'),
			date_hd = $('<div class="date_hd"></div>').appendTo(date_pane),
			date_table = $('<table class="date_table"></table>').appendTo(date_pane);

		// type 为 yyyy-mm-dd 时候 就不显示时间
		if(options.type == 'yyyy-mm-dd HH:MM' || options.type == 'yyyy-mm-dd HH:MM:SS') {
			var	date_time = $('<div class="date_time"><span class="spinner"><input type="text" class="spinner-text">'+
        '<i class="spinner-arrow spinner-arrow-up"></i><i class="spinner-arrow spinner-arrow-down"></i></span></div>')
			.appendTo(date_pane);
		}
		var	date_button = $('<div class="date_button"><a href="javascript:void(0)" class="date-current">今天</a>'+
      '<a href="javascript:void(0)" class="date-closed">关闭</a><a href="javascript:void(0)" class="date-ok">确定</a></div>')
      .appendTo(date_pane);

		date_hd.html("<a class='date_pre' href='javascript://' rel='prev'>&lt;</a><a class='date_next' href='javascript://' rel='next'>&gt;</a>");

		var date_txt = $('<div class="date_txt"></div>').appendTo(date_hd),
			date_set = $('<div class="date_set"></div>').appendTo(date_hd),
			html = "";
		for(var i = options.beginyear; i < options.endyear; i++) {
			html +="<option value='"+i+"'>"+i+"</option>";
		}
		var year_list = $('<select class="year_set"></select>').html(html).appendTo(date_set).val(defYear);
		date_set.append(" - ");
		html = '';
		for(var i = 0; i < 12; i++) {
			html += '<option value="'+(i+1)+'">'+self.language.monthList[i]+'</option>';
		}
		var month_list = $('<select class="month_set"></select>').html(html).appendTo(date_set).val(defMonth);

		html = '<thead><tr>';
		// 遍历一周7天
		for(var i = 0; i < 7; i++) {
			html += "<th class='"
			// 周末高亮
			if(i == saturday) {
				html+= " sat";
			}else if(i == sunday) {
				html+= " sun";
			};
			html+="'>";
			html+= (i+options.wday * 1 < 7) ? self.date_name_week[i+options.wday] : self.date_name_week[i+options.wday - 7];
			html+="</th>";
		};
		html +="</tr></thead>";
		html +="<tbody></tbody>";
		date_table.html(html);

		// 面板及背景遮挡层插入到页面中
		date_pane.appendTo("body");

		// 创建遮罩层的目地是:只显示一个日历面板
		var block_bg=$("<div class='cxcalendar_lock'></div>").appendTo("body");

		// 赋值 全局
		self.dateTxt = date_txt;
		self.yearList = year_list;
		self.monthList = month_list;
		self.dateTable = date_table;
		self.saturday = saturday;
		self.sunday = sunday;
		self.datePane = date_pane;
		self.blockBg = block_bg;
		self.dateSet = date_set;
		self.defYear = defYear;
		self.defMonth = defMonth;
		self.dateTime = date_time;

		//  根据当前的时间 渲染时分秒
		self._renderTime(self.date);

		// 根据年份 月份来渲染天
		self._renderBody(defYear,defMonth);
	},

	// 返回 年月分的 天数
	_dayNumOfMonth: function(Year,Month){
		var d = new Date(Year,Month,0);
		return d.getDate();
	},
	/*
	 * 根据当前的时间,渲染时分秒
	 */
	_renderTime: function(date){
		var self = this,
			options = self.options;
		var hours = new Date(date).getHours(),
			minutes = new Date(date).getMinutes(),
			seconds = new Date(date).getSeconds(),
			curTime;
		if(hours < 10) {
			hours = '0' + hours;
		}
		if(minutes < 10) {
			minutes = '0' + minutes;
		}
		if(seconds < 10) {
			seconds = '0' + seconds;
		}
		if(options.type == 'yyyy-mm-dd HH:MM:SS') {
			curTime = hours + ":" + minutes + ":" + seconds;
		}else if(options.type == 'yyyy-mm-dd HH:MM') {
			curTime = hours + ":" + minutes;
		}
		$(self.dateTime).find('.spinner-text').val(curTime);
	},
	/*
	 * 渲染日历天数
	 * @param {y,m} 年 月
	 */
	_renderBody: function(y,m){
		var self = this;
		var options = self.options;
		if(m < 1) {
			y--;
			m = 12;
		}else if(m > 12) {
			y++;
			m = 1;
		}
		var tempM = m,
			cur_m = m;

		m--;  // 月份从0开始的
		var prevMonth = tempM - 1,  //上个月的月份
			prevDay = self._dayNumOfMonth(y,tempM - 1), // 上个月的天数
			nextMonth = tempM + 1,   // 下个月的月份
			nextDay = self._dayNumOfMonth(y,tempM + 1),  //下个月的天数
			curDay = self._dayNumOfMonth(y,tempM);       // 当前月份的天数

		self.month_day[1]=28+self._leapYear(y);  //闰年的话 29天 否则 28天

		var temp_html = "",
			temp_date = new Date(y,m,1);
		var now_date = new Date();
		now_date.setHours(0);
		now_date.setMinutes(0);
		now_date.setSeconds(0);

		// 如果输入框有值的话
		if(self.targetCls.val().length > 0) {
			var val_date=self._dateParse(self.targetCls.val())
		}
		val_date=new Date(val_date);
		if(isNaN(val_date.getFullYear())){
			val_date=null;
		};

		// 获取当月的第一天,确切地说,判断首天在表格体中出现的位置
		var firstDay = temp_date.getDay() - options.wday < 0 ?
			temp_date.getDay() - options.wday + 7 :
			temp_date.getDay() - options.wday;

		// 每月所需要的行数
		var monthRows = Math.ceil((firstDay+self.month_day[m]) / 7);
		var td_num,
			day_num,
			diff_now,
			diff_set;
		var disabled;
		for(var i= 0; i < monthRows; i++) {
			temp_html += "<tr>";
			for(var j = 0; j < 7; j++) {
				td_num=i*7+j;
				day_num=td_num-firstDay+1;
				if(day_num<=0) {
					if(day_num == 0) {
						day_num = prevDay - day_num
						text_m = prevMonth
					}else {
						day_num = prevDay + day_num;
						text_m = prevMonth
					}

				}else if(day_num > self.month_day[m]){
					day_num = day_num - curDay;
					text_m = nextMonth
				}else {
					text_m 	= cur_m;
				}
				temp_html+="<td";
				if(typeof(day_num) == 'number') {
					diff_now=null;
					diff_set=null;
					temp_date = new Date(y,m,day_num);

					if(text_m == cur_m) {
						diff_now=Date.parse(now_date)-Date.parse(temp_date);
						diff_set=Date.parse(val_date)-Date.parse(temp_date);
					}
					if(cur_m > text_m || cur_m < text_m) {
						disabled = 'disabled';
					}else {
						disabled = "";
					}
					temp_html+=(" title='"+y+options.separator+tempM+options.separator+day_num+"' class='num "+disabled+"");

					// 高亮周末、今天、选中
					if(diff_set==0){    //选中的时候 增加select 类名
						temp_html+=" selected";
					}else if(diff_now==0){
						temp_html+=" now";   // 当前时间增加now类名
					}else if(j==self.saturday){
						temp_html+=" sat";   // 周六增加sat类名
					}else if(j==self.sunday){
						temp_html+=" sun";   // 周日增加sun类名
					};
					temp_html+=("'");
				};
				temp_html+=(" date-day='"+day_num+"'>"+day_num+"</td>");
			}
			temp_html+="</tr>";
		}

		$(self.dateTable).find("tbody").html(temp_html);
		$(self.dateTxt).html("<span class='y'>"+y+"</span>"+options.language.year+"<span class='m'>"+options.language.monthList[m]+"</span>"+options.language.month);
		$(self.yearList).val(y);
		$(self.monthList).val(m+1);

		return this;
	},
	_dateParse: function(date){
		var newdate = date;
		newdate=newdate.replace(/\./g,"/");
		newdate=newdate.replace(/-/g,"/");
		newdate=newdate.replace(/\//g,"/");
		newdate=Date.parse(newdate);
		return newdate;
	},
	/*
	 * 判断是否是闰年
	 * @param y 年份
	 * 1.能被4整除且不能被100整除 2.能被100整除且能被400整除
	 */
	_leapYear: function(y) {
		return ((y%4==0 && y%100!=0) || y%400==0) ? 1 : 0;
	},
	_bindEnv: function(){
		var self = this;
		var options = self.options;
		$(self.targetCls).unbind('click').bind('click',function(){
			self.show();

			// 渲染时分秒
			self._renderTime(new Date());
		});

		// 关闭面板事件
		self.blockBg.unbind('click').bind("click",function(){
			self.hide();
		});

		// 点击上一页 下一页事件
		self.datePane.delegate('a','click',function(){
			if(!this.rel){return};
			var _rel = this.rel;
			if(_rel == 'prev') {
				self._renderBody(self.yearList.val(),parseInt(self.monthList.val(),10) -1);
				return;
			}else if(_rel == 'next') {
				self._renderBody(self.yearList.val(),parseInt(self.monthList.val(),10) +1);
				return;
			}
		});

		// 选择日期事件
		self.datePane.delegate('td','click',function(){
			var _this = $(this);
			if(_this.hasClass('num') && !_this.hasClass('disabled')) {
				self.dateTable.find("td").removeClass("selected");
				_this.addClass("selected");
				var day = _this.attr("date-day");
				if(options.type == 'yyyy-mm-dd') {
					self._selectDay(day);
				}

			}
		});

		// 显示年月选择
		self.dateTxt.unbind('click').bind("click",function(){
			self.dateTxt.hide();
			self.dateSet.show();
		});

		//更改年月事件
		self.yearList.unbind('change').bind("change",function(){
			self._renderBody(self.yearList.val(),self.monthList.val());
		});
		self.monthList.unbind('change').bind("change",function(){
			self._renderBody(self.yearList.val(),self.monthList.val());
		});

		// 点击确定按钮
		self.datePane.delegate('.date-ok','click',function(){
			var nums = $(self.dateTable).find('.num'),
				flag = false;
			for(var i = 0, ilen = nums.length; i < ilen; i++) {
				if($(nums[i]).hasClass("selected")) {
					var day = $(nums[i]).attr("date-day");
					flag = true;
					break;
				}else {
					if($(nums[i]).hasClass("now")) {
						var day = $(nums[i]).attr("date-day");
						flag = true;
						continue;
					}
				}
			}
			if(flag) {
				self._selectDay(day);
			}
		});
		// 点击关闭按钮
		self.datePane.delegate('.date-closed','click',function(){
			self.hide();
		});

		// 点击今天按钮
		self.datePane.delegate('.date-current','click',function(){
			// 获取当前第几号
			var date = new Date(),
				curDay = date.getDate(),
				curYear = date.getFullYear(),
				curMonth = date.getMonth() + 1;
			self._renderBody(curYear,curMonth);

			self.dateTable.find("td.num").removeClass("selected");
			self.dateTable.find("td.num").each(function(){
				var day = $(this).attr("date-day");
				if(day == curDay) {
					$(this).addClass("selected");
				}
			});
		});

		// 点击箭头向上按钮
		self.datePane.delegate('.spinner-arrow-up','click',function(){
			self._inputValChange(true);
		});

		// 点击箭头向下按钮
		self.datePane.delegate('.spinner-arrow-down','click',function(){
			self._inputValChange(false);
		});
	},
	/*
	 * 选择某一天的时候 把值存入输入框里 且面板隐藏
	 * @_selectDay {private}
	 */
	_selectDay: function(d) {
		var self = this;
		var year,
			month;
		month = self.monthList.val();
		day = d;
		var options = self.options;
		month="0" + self.monthList.val();
		day= "0" + d;
		month=month.substr((month.length-2),month.length);
		day=day.substr((day.length-2),day.length);

		if(options.type == 'yyyy-mm-dd') {
			self.targetCls.val(self.yearList.val()+options.separator+month+options.separator+day);
			self.hide();
			self.callback && $.isFunction(self.callback) && self.callback(self.yearList.val()+options.separator+month+options.separator+day);
		}else if(options.type == 'yyyy-mm-dd HH:MM:SS' || options.type == 'yyyy-mm-dd HH:MM'){
			self.targetCls.val(self.yearList.val()+options.separator+month+options.separator+day+ " " +$(self.dateTime).find('.spinner-text').val());
			self.hide();
			self.callback && $.isFunction(self.callback) && self.callback(self.yearList.val()+options.separator+month+options.separator+day+ " " +$(self.dateTime).find('.spinner-text').val());
		}
		return this;
	},
	/*
	 * 点击向上或者向下 时间输入框值改变
	 * @param {flag} boolean 布尔型。如果为true 则是往上加 否则是往下减
	 */
	_inputValChange: function(flag){
		var self = this,
			options = self.options;

		var inputVal = $(self.datePane).find('.spinner-text').val();
		var arrs = inputVal.split(":"),
			hour = arrs[0] ? arrs[0] : '',
			minute = arrs[1] ? arrs[1] : '',
			second = arrs[2] ? arrs[2] : '';
		if(flag) {
			hour++;
			if(hour >= 24) {
				return;
			}else if(hour < 10) {
				hour = "0" + hour;
			}
		}else {
			hour--;
			if(hour < 0) {
				return;
			}else if(hour < 10) {
				hour = '0' + hour;
			}
		}
		var val;
		if(options.type == "yyyy-mm-dd HH:MM:SS") {
			val = hour + ":" + minute + ":" + second;

		}else if(options.type == 'yyyy-mm-dd HH:MM') {
			val = hour + ":" + minute;

		}
		$('.spinner-text',self.datePane).val(val);

	},
	/*
	 * 显示日历面板
	 * @method  show {public}
	 */
	show: function(){
		var self = this;
		if(self.flag) {
			return;
		}
		var doc_w = document.body.clientWidth,
			doc_h = document.body.clientHeight,
			pane_top = self.targetCls.offset().top,
			pane_left = self.targetCls.offset().left,
			obj_w = self.targetCls.outerWidth(),
			obj_h = self.targetCls.outerHeight();
		pane_top= pane_top+obj_h;
		self.datePane.css({"top":pane_top,"left":pane_left}).show();
		self.blockBg.css({width:doc_w,height:doc_h}).show();
		self.flag = true;
		return this;
	},
	/*
	 * 清除日期
	 * @method clear {public}
	 */
	clear: function(){
		var self = this;
		self.targetCls.val('');
		self._renderBody(self.defYear,self.defMonth);
		self.hide();
		return this;
	},
	/*
	 * 获取当前选中的日期
	 * @method getValue {public}
	 * @return val
	 */
	 getValue: function(){
		var self = this;
		return self.targetCls.val();
	 },
	/*
	 * 隐藏日历面板
	 */
	hide: function(){
		var self = this;
		if(!self.flag) {return;}
		self.datePane.hide();
		self.blockBg.hide();
		self.dateSet.hide();
		self.dateTxt.show();
		self.flag = false;
		return this;
	}
 });

 var defaults = {
	targetCls        :        '',             //渲染日历的class
	beginyear        :        1949,           //开始年份
	endyear          :        2050,           //结束年份
	date             :        new Date(),     // 默认日期
	type             :        "yyyy-mm-dd",	  // 日期格式
	separator        :        "-",			  // 日期链接符
	wday             :        0,			  // 周第一天
	language         :       {
								year:"年",
								month:"月",
								monthList:["1","2","3","4","5","6","7","8","9","10","11","12"],
								weekList:["日","一","二","三","四","五","六"]}
 };

猜你喜欢

转载自schifred.iteye.com/blog/2300667