/**
 * 将2位的年份转成4位年份
 * 如果年份小于30，则前面加20，否则加19，即:
 * <pre>
 *    getFullYear(02) => 2002
 *    getFullYear(72) => 1972
 * </pre>
 *
 * @param y 需要转换的年份
 * @return 如果不是数字，或者大于99，直接返回0；否则返回4为年份。
 */
function getFullYear(y){
	if(isNaN(y) || y < 0 || y >= 100) return 0;

	return (y<30 ? 2000 : 1900) + y;
}

/**
 * 检测指定的时分秒是否是一个合法的时间
 *
 * @param 按顺序分别为时分秒，时分秒可以为空，为空默认为0.
 * @return 如果是合法的时间，返回true；否则返回false。
 * @author whj
 */
function isValidTime(hh, mm, ss){
	hh |= 0;
	mm |= 0;
	ss |= 0;
	return hh >=0 && hh <= 23 
		&& mm >= 0 && mm <=59 
		&& ss >=0 && ss <= 59;
}

/**
 * 检测指定的年月日是否是一个合法的日期
 *
 * @param year 年
 * @param month 月
 * @param day 日
 * @return 如果是合法的日期，返回true；否则返回false。
 * @author whj
 */
function isValidDate(year, month, day){
	var date = new Date(year, month-1, day);
	return typeof(date) == "object" 
		&& year == date.getFullYear() 
		&& month == (date.getMonth()+1) 
		&& day == date.getDate();
}

/**
 * 将字符串装换成一个日期对象
 *
 * @param str 待装换的字符串
 * @param fmtDate 日期格式，如果不是dmy，则认为是ymd
 * @param fmtTime 时间格式，为hm,hms,hm_s(秒为可选)，不指定，则认为没有时间部分
 * @return 如果是一个合法的日期，则返回日期对象；否则返回null
 * @see parseDate(str, fmtDate, fmtTime)
 */
function toDate(str, fmtDate, fmtTime) {
	var parts = parseDate(str, fmtDate, fmtTime);
	if(parts == null) return null;

	return new Date(parts[0], parts[1]-1, parts[2], parts[3]|0, parts[4]|0, parts[5]|0);
}

/**
 * 将字符串按照指定格式解析成一个包含年月日时分秒的整型数组
 * 数组从下标0开始，依次为年月日时分秒。分隔符可以是“-./”。
 *
 * @param str 指定的字符串
 * @param fmtDate 日期格式，如果不是dmy，则认为是ymd
 * @param fmtTime 时间格式，为hm,hms,hm_s(秒为可选)，不指定，则认为没有时间部分
 * @return 如果符合格式，返回包含年月日时分秒的数组；否则，返回null
 * @author whj
 */
function parseDate(str, fmtDate, fmtTime) {
	var reg = null;

	if("dmy" == fmtDate){
		reg = "^(\\d{1,2})([-./])(\\d{1,2})\\2((\\d{4})|(\\d{2}))";
	} else if ("ymd" == fmtDate){
		//alert(fmtDate);
		reg = "^(\\d{1,4})([-])(\\d{1,2})([-])(\\d{1,2})";
	} else {
		reg = "^((\\d{4})|(\\d{2}))([-./])(\\d{1,2})\\4(\\d{1,2})";
	}

	if(!isNull(fmtTime)) {
		if("hm" == fmtTime) reg += "\\s+(\\d{1,2}):(\\d{1,2})";
		else if("hms" == fmtTime) reg += "\\s+(\\d{1,2}):(\\d{1,2}):(\\d{1,2})";
		else if("hm_s" == fmtTime) reg += "\\s+(\\d{1,2}):(\\d{1,2})(:(\\d{1,2})){0,1}";
	}
	reg += "$";

	var d = getDateFields(str.match(new RegExp(reg)), fmtDate);

	if(d instanceof Array
		&& isValidDate(d[0], d[1], d[2]) 
		&& isValidTime(d[3], d[4], d[5])) return d;

	return null;
}

/**
 * 按照年月日时分秒的顺序返回数组
 * 仅适用于在上面各种parseXXX中调用。

 * @param m 包含正则表达式匹配结果数组
 * @param fmt 指定日期格式，如果不是dmy格式，则全认为是ymd的格式
 * @return 返回按照年月日时分秒排列的数组
 */
function getDateFields(m, fmt) {
	if(!(m instanceof Array) || m.length < 3) return null;
	var d = new Array();
	if("dmy" == fmt) {
		d[0] = (m[5] != null && m[5].length == 4) ? m[5] : getFullYear(parseInt(m[6], 10));
		d[1] = m[3]*1;
		if(d[1] == 0) d[1] = 12;
		d[2] = m[1]*1;		
	} else {
		d[0] = (m[2] != null && m[2].length == 4) ? m[2] : getFullYear(parseInt(m[3], 10));
		d[1] = m[5]*1;
		if(d[1] == 0) d[1] = 12;
		d[2] = m[6]*1;
	}
	if(m.length >= 9) {
		d[3] = m[7]*1;
		d[4] = m[8]*1;
	}
	if(m.length == 10) d[5] = m[9]*1;
	else if(m.length == 11) d[5] = m[10]|0;

	return d;
}

/**
 * 计算2个日期的间隔，精确到秒
 * 总是以后一个日期减前一个日期，返回d days hh:mm:ss形式的字符串，
 * 不够一天，则仅返回时间部分
 * 
 * @param startDate 开始日期
 * @param endDate 结束日期
 * @return 返回d days hh:mm:ss形式的字符串，如果有个日期为空，则返回空字符串。
 * @author whj
 */
function computeTimeInDToS(startDate, endDate) {
	if (startDate == null || endDate == null)
		return "";

	var is = computeTimeInDay(startDate, endDate);
	var s = (is[0] > 0 ? "" : "-")
			+ (is[1] == 0 ? "" : (is[1] + " days "))
			+ (is[2]<10?"0"+is[2]:is[2])
			+ ":"
			+ (is[3]<10?"0"+is[3]:is[3])
			+ ":"
			+ (is[4]<10?"0"+is[4]:is[4]);
	return s;
}

/**
 * 计算2个日期的间隔，精确到分钟
 * 总是以后一个日期减前一个日期，返回d days hh:mm形式的字符串，
 * 不够一天，则仅返回时间部分
 * 
 * @param startDate 开始日期
 * @param endDate 结束日期
 * @return 返回[d]days hh:mm形式的字符串，如果有个日期为空，则返回空字符串。
 * @author whj
 */
function computeTimeInDToM(startDate, endDate) {
	if (startDate == null || endDate == null)
		return "";

	var is = computeTimeInDay(startDate, endDate);
	var s = (is[0] > 0 ? "" : "-")
			+ (is[1] == 0 ? "" : (is[1] + " days "))
			+ (is[2]<10?"0"+is[2]:is[2])
			+ ":"
			+ (is[3]<10?"0"+is[3]:is[3]);

	return s;
}

/**
 * 计算2个日期的间隔
 * 总是以后一个日期减前一个日期，返回一个长度为5的整型数组，下标从0开始
 * 依次为days, hours, mins, seconds和ms。
 * 
 * @param startDate
 * @param endDate
 * @return 如果其中一个日期为null，则返回长度为0的数组；否则返回依次保存
 * 间隔天数、小时数、分钟数、秒数及毫秒数的数组。
 */
function computeTimeInDay(startDate, endDate) {
	if (startDate == null || endDate == null)
		return new Array();

	var is = new Array();
	var t = endDate.getTime() - startDate.getTime();
	if(t<0) {is[0] = -1; t *= -1;}
	else is[0] = 1;
	is[5] = t % 1000;
	t = Math.floor(t/1000);
	for (var i = 4; i > 1; i--) {
		is[i] = t % 60;
		t = Math.floor(t/60);
	}

	is[1] = t;

	return is;
}


function strIsValidDate(dateStr) {
	var matchArray = dateStr.match(/^[0-9]+-[0-1][0-9]-[0-3][0-9]$/)
	if (matchArray == null) {
	  return false;
	}
	return true;
}