/**
 * 工具类 - 时间相关
 * @module  js/utils-time
 * @description 常用时间工具方法集合
 * @author  liu_yang17<liu_yang17@dahuatech.com>
 * @version 7.02
 */
Date.prototype.format = function (format) {
    let format1 = format;
    var o = {
        "M+": this.getMonth() + 1,
        "d+": this.getDate(),
        "H+": this.getHours(),
        "m+": this.getMinutes(),
        "s+": this.getSeconds(),
        "q+": Math.floor((this.getMonth() + 3) / 3),
        "S+": this.getMilliseconds()
    };

    if (!format1) {
        format1 = "yyyy-MM-dd";
    }

    if (/(y+)/.test(format1)) {
        format1 = format1.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    }

    if (/(S+)/.test(format1)) {
        format1 = format1.replace(RegExp.$1, (this.getMilliseconds() + "").substr(3 - RegExp.$1.length));
    }

    for (var k in o) {
        if (new RegExp("(" + k + ")").test(format1)) {
            format1 = format1.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
        }
    }
    return format1;
}


var REG = {
    TIME: /^([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/,
    DATE: /^\d{4}-(0[0-9]|1[0-2])-([0-2][0-9]|3[0-1]) ([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/,
    DATE_M_D_Y: /^(0[0-9]|1[0-2])-([0-2][0-9]|3[0-1])-\d{4} ([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/,
    DATE_Z: /^\d{4}(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])T([0-1][0-9]|2[0-3])[0-5][0-9][0-5][0-9]Z$/,
    DATE_Z_S: /^\d{4}(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])T([0-1][0-9]|2[0-3])[0-5][0-9][0-5][0-9][.]\d{0,3}Z$/
}

/**
 * add Zero 月日时分秒补0函数
 */
function addZero(time) {
    let newTime = time > 9 ? time : '0' + time
    return newTime
}

/**
 * 校验时间格式
 * @param {string} time 时间格式，如 10:00:00
 */
function valifyTime(time) {
    const reg = /^\d{2}:\d{2}:\d{2}$/
    return reg.test(time)
}

/**
 * 判定两组时间序列是否存在重复（交叉或包含）
 * @param {array} time1Arr 时间范围，如 [10:00:00, 12:00:00]
 * @param {array} time2Arr 时间范围，如 [09:00:00, 23:00:00]
 */
function isTimeContainTime(time1Arr, time2Arr) {
    let timeArr
    let validate = true
    // 确保两组时间范围格式正确
    if (!Array.isArray(time1Arr) || !Array.isArray(time2Arr)) {
        throw new Error('Please enter two array.')
    }
    if (time1Arr.length !== 2 || time2Arr.length !== 2) {
        throw new Error('Please enter currect time.')
    }
    timeArr = [...time1Arr, ...time2Arr]
    for (let time of timeArr) {
        if (!valifyTime(time)) {
            throw new Error('Please enter currect time.')
        }
    }

    // 检验时间是否存在重复
    if (time2Arr[0] > time1Arr[0] && time2Arr[0] < time1Arr[1] ||
        time2Arr[1] > time1Arr[0] && time2Arr[1] < time1Arr[1]) {
        validate = false;
    }
    if (time1Arr[0] > time2Arr[0] && time1Arr[0] < time2Arr[1] ||
        time1Arr[1] > time2Arr[0] && time1Arr[1] < time2Arr[1]) {
        validate = false;
    }

    return validate
}

/**
 * 将时间转换为UTC时间字符串，支持格式 hh:mm:ss
 * @description 按源格式返回
 * @param {string} timeStr 源时间
 * @returns {object} 包含time和日期偏差
 */
function toISOStringByTime(timeStr) {
    const time = {}
    let date = new Date(`2000/10/24 ${timeStr}`)
    time.d = date.getUTCDate()
    time.h = addZero(date.getUTCHours())
    time.min = addZero(date.getUTCMinutes())
    time.s = addZero(date.getUTCSeconds())

    return {
        offset: time.d - 24,
        time: `${time.h}:${time.min}:${time.s}`
    }
}

/**
 * 将时间转换为UTC时间字符串，支持格式 yyyy-mm-dd hh:mm:ss
 * @description 按源格式返回
 * @param {string} timeStr 源时间
 * @param {string} type str 普通时间格式， utcStr yyyymmddThhmmssZ格式
 */
function toISOStringByDate(timeStr, type = 'str') {
    const time = {}
    let newTime
    let date = new Date(timeStr.replace(/-/g, '/'))
    time.y = date.getUTCFullYear()
    time.m = addZero(date.getUTCMonth() + 1)
    time.d = addZero(date.getUTCDate())
    time.h = addZero(date.getUTCHours())
    time.min = addZero(date.getUTCMinutes())
    time.s = addZero(date.getUTCSeconds())

    if (type === 'utcStr') {
        newTime = `${time.y}${time.m}${time.d}T${time.h}${time.min}${time.s}Z`
    } else {
        newTime = `${time.y}-${time.m}-${time.d} ${time.h}:${time.min}:${time.s}`
    }

    return newTime
}

/**
 * 将时间转换为UTC时间字符串
 * @description 按源格式返回，目前支持格式1970-01-01 00:00:00
 * @param {string} timeStr 源时间
 * @param {string} type str 普通时间格式， utcStr yyyymmddThhmmssZ格式
 */
function toISOString(timeStr, type) {
    try {
        if (REG.DATE.test(timeStr)) {
            // 格式 yyyy-mm-dd hh:mm:ss
            return toISOStringByDate(timeStr, type)

        } else if (REG.TIME.test(timeStr)) {
            // 格式 hh:mm:ss
            return toISOStringByTime(timeStr)
        }
    } catch (e) {
        return ''
    }


    throw new Error('Please enter date as yyyy-mm-dd hh:mm:ss')
}

/**
 * 将UTC时间转换为本地时间字符串，支持格式 hh:mm:ss
 * @description 默认传入的为UTC时间，此处由于各版本浏览器支持性不一，故使用Date.UTC()
 * @param {string} timeStr 源时间
 * @returns {object} 包含time和日期偏差
 */
function toLocaleStringByTime(timeStr) {
    const time = {}

    let timeList = timeStr.split(':');

    let utcDate = Date.UTC(2000, 10, 24, timeList[0], timeList[1], timeList[2]);
    let date = new Date(utcDate);

    time.d = date.getDate()
    time.h = addZero(date.getHours())
    time.min = addZero(date.getMinutes())
    time.s = addZero(date.getSeconds())

    return {
        offset: time.d - 24,
        time: `${time.h}:${time.min}:${time.s}`
    }
}

/**
 * 将UTC时间转换为本地时间字符串，支持格式 yyyy-mm-dd hh:mm:ss
 * @description 默认传入的为UTC时间，此处由于各版本浏览器支持性不一，故使用Date.UTC()
 * @param {string} timeStr 源时间
 * @param {string} type str 普通时间格式， mmDDyy
 */
function toLocaleStringByDate(timeStr, type = 'str') {
    const time = {}

    let newTime = timeStr.split(' ');
    let dateList = newTime[0].split('-');
    let timeList = newTime[1].split(':');

    let utcDate = Date.UTC(dateList[0], dateList[1] - 1, dateList[2], timeList[0], timeList[1], timeList[2]);
    let date = new Date(utcDate);

    time.y = date.getFullYear()
    time.m = addZero(date.getMonth() + 1)
    time.d = addZero(date.getDate())
    time.h = addZero(date.getHours())
    time.min = addZero(date.getMinutes())
    time.s = addZero(date.getSeconds())
    if (type === 'mmDDyy') {
        return `${time.m}-${time.d}-${time.y} ${time.h}:${time.min}:${time.s}`
    }
    return `${time.y}-${time.m}-${time.d} ${time.h}:${time.min}:${time.s}`
}

/**
 * 将UTC时间转换为本地时间字符串
 * @description 默认传入的为UTC时间，目前支持格式1970-01-01 00:00:00
 * @param {string} timeStr 源时间
 */
function toLocaleString(timeStr) {
    if (!timeStr) {
        return
    }
    try {
        if (REG.DATE.test(timeStr)) {
            // 格式 yyyy-mm-dd hh:mm:ss
            return toLocaleStringByDate(timeStr)
        } else if (REG.TIME.test(timeStr)) {
            // 格式 hh:mm:ss
            return toLocaleStringByTime(timeStr)
        } else if (REG.DATE_Z.test(timeStr)) {
            // 格式 yyyymmddThhmmssZ
            let newTime = timeStr.replace(/[^0-9]/g, '')
            let date = `${newTime.slice(0, 4)}-${newTime.slice(4, 6)}-${newTime.slice(6, 8)}`
            let time = `${newTime.slice(8, 10)}:${newTime.slice(10, 12)}:${newTime.slice(12, 14)}`
            return toLocaleStringByDate(`${date} ${time}`)
        } else if (REG.DATE_M_D_Y.test(timeStr)) {
            let newTime = timeStr.split(' ');
            let dateList = newTime[0].split('-');
            let time = newTime[1];

            return toLocaleStringByDate(`${dateList[2]}-${dateList[0]}-${dateList[1]} ${time}`, 'mmDDyy')
        } else if (REG.DATE_Z_S.test(timeStr)) {
            // 格式 yyyymmddThhmmss.000Z  带毫秒的utc格式
            let newTime = timeStr.replace(/[^0-9]/g, '')
            let date = `${newTime.slice(0, 4)}-${newTime.slice(4, 6)}-${newTime.slice(6, 8)}`
            let time = `${newTime.slice(8, 10)}:${newTime.slice(10, 12)}:${newTime.slice(12, 14)}`

            return toLocaleStringByDate(`${date} ${time}`)
        }
    } catch (e) {
        console.log('Please enter date as yyyy-mm-dd hh:mm:ss')
        return ''
    }
    throw new Error('Please enter date as yyyy-mm-dd hh:mm:ss')

}
/**
 * 格式化时间
 * 
 * @param {any} date 
 * @param {any} format 
 * @returns 
 */
function dateFormat(date, format) {
    let format1 = format;
    var o = {
        "M+": date.getMonth() + 1,
        "d+": date.getDate(),
        "H+": date.getHours(),
        "m+": date.getMinutes(),
        "s+": date.getSeconds(),
        "q+": Math.floor((date.getMonth() + 3) / 3),
        "S+": date.getMilliseconds()
    };

    if (!format1) {
        format1 = "yyyy-MM-dd";
    }

    if (/(y+)/.test(format1)) {
        format1 = format1.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    }

    if (/(S+)/.test(format1)) {
        format1 = format1.replace(RegExp.$1, (date.getMilliseconds() + "").substr(3 - RegExp.$1.length));
    }

    for (var k in o) {
        if (new RegExp("(" + k + ")").test(format1)) {
            format1 = format1.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
        }
    }
    return format1;
}
/**
 * 获取当前UTC时间
 */
function getCurrentUTCTime() {
    let retStr = '';
    let dateStr  = dateFormat(new Date(), 'yyyy-MM-dd HH:mm:ss');
    if(dateStr){
        retStr = toISOString(dateStr, 'utcStr');
    }
    return retStr
}
/**
 * 获取当前时间
 */
function getCurrentTime() {
    let retStr = '';
    let dateStr  = dateFormat(new Date(), 'yyyy-MM-dd HH:mm:ss');
    return dateStr
}
/**
 * 获取UTC时间
 */
function getUTCTimeByTime(time) {
    let retStr = '';
    let dateStr  = dateFormat(new Date(time), 'yyyy-MM-dd HH:mm:ss');
    if(dateStr){
        retStr = toISOString(dateStr, 'utcStr');
    }
    return retStr
}
/**
 * 获取当前浏览器客户端的时区
 * @description +0800为东八区
 * @returns {string} such as +0000 +0545
 */
function getTimezoon() {
    let timezoonOffset = new Date().getTimezoneOffset();
    const flag = timezoonOffset > 0 ? '-' : '+';

    timezoonOffset = Math.abs(timezoonOffset);

    const hours = Math.floor(timezoonOffset / 60);
    const minute = timezoonOffset % 60;
    return flag + addZero(hours) + addZero(minute);
}

/**
 * 格式化时间为对象形式
 *
 * @description
 * 接收Date、数字或字符串格式的UTC时间、UTC时间*1000（单位秒）
 * 转换为时间对象
 *
 * @method dateToObject
 * @param {Object | String | Number} param 时间
 * @returns {object} 日期结果对象
 */
function dateToObject(param) {
    let date = null

    if (typeof param === 'object') {
        date = param;
    } else if (typeof param === 'string') {
        if (param.toString().length === 13) {
            date = new Date(param.replace(/-/g, '/'));
        } else if (param.toString().length === 10) {
            date = new Date(param * 1000);
        } else {
            date = new Date(param.replace(/-/g, '/'));
        }
    } else if (typeof param === 'number') {
        date = new Date(param);
    }

    if (!date) {
        return {};
    }

    const dateObj = {
        year: date.getFullYear(),
        month: addZero(date.getMonth() + 1),
        day: addZero(date.getDate()),
        hour: addZero(date.getHours()),
        minute: addZero(date.getMinutes()),
        second: addZero(date.getSeconds())
    }

    return dateObj
}

/**
 * 根据时间字符串获取年月日日期 20180530,2018年9月30日;
 * @param param
 */
function getDateString(param,type=0){
    let date = new Date(param);
    let year = date.getFullYear()+"";
    let month=(date.getMonth()+1)+"";
    let day=date.getDate();
    let tmp="";
    month=month<10?"0"+month:month;
    day=day<10?"0"+day:day;
    if(type===0){
        tmp=year+month+day;
    }else if(type===1){
        tmp=year+"-"+month+"-"+day;
    }else{
        tmp=param;
    }

    return tmp;
}

/**
 * 根据时间字符串获取时分秒;
 * @param param
 */
function getTimeString(param,type=0) {
    let date = new Date(param);
    let hour = date.getHours();
    let min = date.getMinutes();
    let sec = date.getSeconds();
    hour = hour < 10 ? "0" + hour : hour;
    min = min < 10 ? "0" + min : min;
    sec = sec < 10 ? "0" + sec : sec;
    let tmp = "";
    if (type === 0) {
        tmp =  hour + ":" + min + ":" + sec;
    }

    return tmp;
}

/**
 * 获取系统的当前时间;
 * @param param
 */
function getNowFormatData(type=0){
    let date = new Date();
    let year = date.getFullYear();
    let month=date.getMonth()+1;
    let day=date.getDate();
    let hour = date.getHours();
    let min = date.getMinutes();
    let sec = date.getSeconds();
    month=month<10?"0"+month:month;
    day=day<10?"0"+day:day;
    hour=hour<10?"0"+hour:hour;
    min=min<10?"0"+min:min;
    sec=sec<10?"0"+sec:sec;

    let tmp="";
    if(type===0){
        tmp=year+month+day+" "+hour+":"+min+":"+sec;
    }else if(type===1){
        tmp=year+"-"+month+"-"+day+" "+hour+":"+min+":"+sec;
    }else{
        tmp=param;
    }

    return tmp;
}
/**
 * 格式化时间
 *
 * @param {any} date
 * @param {any} format
 * @returns
 */
function dateFormat(date, format) {
    let format1 = format;
    var o = {
        "M+": date.getMonth() + 1,
        "d+": date.getDate(),
        "H+": date.getHours(),
        "m+": date.getMinutes(),
        "s+": date.getSeconds(),
        "q+": Math.floor((date.getMonth() + 3) / 3),
        "S+": date.getMilliseconds()
    };

    if (!format1) {
        format1 = "yyyy-MM-dd";
    }

    if (/(y+)/.test(format1)) {
        format1 = format1.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    }

    if (/(S+)/.test(format1)) {
        format1 = format1.replace(RegExp.$1, (date.getMilliseconds() + "").substr(3 - RegExp.$1.length));
    }

    for (var k in o) {
        if (new RegExp("(" + k + ")").test(format1)) {
            format1 = format1.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
        }
    }
    return format1;
}
/**
 * valifyTime 校验时间格式
 * isTimeContainTime 判定两组时间序列是否存在重复（交叉或包含）
 * toISOString 将时间转换为UTC时间字符串
 * toLocaleString 将时间转换为本地时间字符串
 * getTimezoon 获取当前时区
 */

