/** * this util module is about to verify, fix dates and time format * @module angle-util/dateUtil */ // 定义type type SecondsType = 'yes' | 'no' | 'dynamic' // 'yes'一直显示秒,'no'不显示秒, 'dynamic'动态显示(时间低于设定值时,显示秒,其他时候不显示秒) type JsDate = string | number | Date type FormatType = 'short' | 's' | 'long' | 'l' // 格式化的类型,'short'与's'指代短类型(e.g. 2016-1-12 18:02:10),'long'与'l'指代长类型(e.g. 2016-01-12 18:02:10)。默认是长类型 type StrictFormatType = 'short' | 'long' type DateType = 'DT' | 'D' | 'T' // 日期时间类型,'DT'代表日期时间,'D'代表日期,'T'代表时间 // 定义shape export interface ReadableTimeParams { seconds: SecondsType // 秒模式 secondsDynamicLimit?: number // 秒动态显示设定值 } export interface ReadableTimeInfo { days: number // 天数 hours: number // 小时数 minutes: number // 分钟数 seconds: number // 秒数 timeString: string // 可阅读的时间字符串,例如'1天2小时3分钟4秒' } export default { /** * 转化秒数为可阅读时间 * @author youngbeen * @param { integer } time - 待转化的时间秒数 * @param { object } [params] - [配置参数] * @param { string } [params.seconds] - 秒模式,默认'yes'一直显示秒,'no'不显示秒, 'dynamic'动态显示(时间低于设定值时,显示秒,其他时候不显示秒) * @param { integer } [params.secondsDynamicLimit] - 秒动态显示设定值,默认60秒,即默认低于一分钟时则显示秒,其他时候不显示秒(该参数匹配seconds为'dynamic'时生效) * @return { object } data - 格式化后的可阅读时间 * @return { integer } data.days - 天数 * @return { integer } data.hours - 小时数 * @return { integer } data.minutes - 分钟数 * @return { integer } data.seconds - 秒数 * @return { string } data.timeString - 可阅读的时间字符串,例如'1天2小时3分钟4秒' * @example * console.log(timeUtil.fixTime(23881)) // { days: 0, hours: 6, minutes: 38, seconds: 1, timeString: "6小时38分钟1秒" } * @example * console.log(timeUtil.fixTime(23881, { seconds: 'no' })) // { days: 0, hours: 6, minutes: 38, seconds: 1, timeString: "6小时38分钟" } */ getReadableTimeBySeconds (time: number, params?: ReadableTimeParams): ReadableTimeInfo { if (time) { let secondsShow: SecondsType = 'yes' let secondsDynamicLimit: number = 60 if (params && params.seconds === 'no') { secondsShow = 'no' } else if (params && params.seconds === 'dynamic') { secondsShow = 'dynamic' params.secondsDynamicLimit ? secondsDynamicLimit = params.secondsDynamicLimit : secondsDynamicLimit } let isNegative = false if (time < 0) { isNegative = true time = Math.abs(time) } let allSeconds: number = time let allMinutes: number = Math.floor(allSeconds / 60) let seconds: number = allSeconds % 60 let allHours: number = Math.floor(allMinutes / 60) let minutes: number = allMinutes % 60 let allDays: number = Math.floor(allHours / 24) let hours: number = allHours % 24 // let allMonthes = Math.floor(allDays / 30) // let days = allDays % 30 // let allYears = Math.floor(allMonthes / 12) // let monthes = allMonthes % 12 let result: string = '' let hourKey: boolean = false let minuteKey: boolean = false // if (allYears) { // result += allYears + 'y' // } // if (monthes) { // result += monthes + 'M' // } if (allDays) { result += (isNegative ? '-' : '') + allDays + '天' hourKey = true } if (hours || hourKey) { result += (isNegative ? '-' : '') + hours + '小时' minuteKey = true } if (minutes || minuteKey) { result += (isNegative ? '-' : '') + minutes + '分钟' } if (secondsShow === 'yes') { // 一直显示秒 result += (isNegative ? '-' : '') + seconds + '秒' } else if (secondsShow === 'no') { // 一直不显示秒 } else if (secondsShow === 'dynamic') { // 动态显示秒 if (time < secondsDynamicLimit) { result += (isNegative ? '-' : '') + seconds + '秒' } } // 处理不超过1分钟的时间却又省略秒位的字符串 if (!result) { result += '0分钟' } return { days: isNegative ? -1 * allDays : allDays, hours: isNegative ? -1 * hours : hours, minutes: isNegative ? -1 * minutes : minutes, seconds: isNegative ? -1 * seconds : seconds, timeString: result } } else { // 未传入time或者time为0 if (params && params.seconds === 'no') { return { days: 0, hours: 0, minutes: 0, seconds: 0, timeString: '0分钟' } } else { return { days: 0, hours: 0, minutes: 0, seconds: 0, timeString: '0秒' } } } }, formatDateTime (format: string, time?: JsDate): string { if (!format || (!time && time !== undefined)) { return '' } let date: JsDate = '' if (time) { if (time instanceof Date) { date = new Date(time) } else if (typeof time === 'string' && !/Z$/i.test(time)) { const d = time.match(/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/) if (d) { const m = parseInt(d[2], 10) - 1 || 0 const ms = (d[7] || '0').substring(0, 3) date = new Date(parseInt(d[1], 10), m, parseInt(d[3], 10) || 1, parseInt(d[4], 10) || 0, parseInt(d[5], 10) || 0, parseInt(d[6], 10) || 0, parseInt(ms, 10)) } else { date = new Date(time) } } else { date = new Date(time) } // if (typeof (time) === 'string') { // // 字符串日期需要做下特殊处理 // // NOTE 为了兼容iOS浏览器,将-变换为/ (iOS浏览器不支持带-的日期格式) // date = new Date(time.replace(/-/g, '/')) // } else { // // Date和number类型的日期 // date = new Date(time) // } } else { date = new Date() } const Y: string = date.getFullYear() + '' const M: number = date.getMonth() + 1 const D: number = date.getDate() const H: number = date.getHours() const m: number = date.getMinutes() const s: number = date.getSeconds() return format.replace(/YYYY|yyyy/g, Y) .replace(/YY|yy/g, Y.substr(2, 2)) .replace(/MM/g, (M < 10 ? '0' : '') + M) .replace(/DD/g, (D < 10 ? '0' : '') + D) .replace(/HH|hh/g, (H < 10 ? '0' : '') + H) .replace(/mm/g, (m < 10 ? '0' : '') + m) .replace(/ss/g, (s < 10 ? '0' : '') + s) }, /** * 获取格式化日期时间 * @author youngbeen * @param { string } time - 可转化为js date类型的时间,字符串等 * @param { string } [type] - 格式化的类型,'short'与's'指代短类型(e.g. 2016-1-12 18:02:10),'long'与'l'指代长类型(e.g. 2016-01-12 18:02:10)。默认是长类型 * @param { string } [dateSep] - 用来分隔日期的字符。默认是'-',用 - 分隔 * @return { string } 格式化后的日期时间字符串或者空字符串 * @example * console.log(dateUtil.getDateTime()) // '' * @example * let time = 1452592930000 * console.log(dateUtil.getDateTime(time)) // '2016-01-12 18:02:10' * console.log(dateUtil.getDateTime(time, 'short', '.')) // '2016.1.12 18:02:10' */ getDateTime (time: JsDate, type: FormatType = 'long', dateSep: string = '-'): string { if (time) { if (type === 'short' || type === 's') { // short type return this.fixDateTime(time, 'DT', 'short', dateSep) } else { // default as long type return this.fixDateTime(time, 'DT', 'long', dateSep) } } else { return '' } }, /** * 获取格式化日期 * @author youngbeen * @param { string } time - 可转化为js date类型的时间,字符串等 * @param { string } [type] - 格式化的类型,'short'与's'指代短类型(e.g. 2016-1-12),'long'与'l'指代长类型(e.g. 2016-01-12)。默认是长类型 * @param { string } [dateSep] - 用来分隔日期的字符。默认是'-',用 - 分隔 * @return { string } 格式化后的日期字符串或者空字符串 * @example * console.log(dateUtil.getDate()) // '' * @example * let time = 1452592930000 * console.log(dateUtil.getDate(time)) // '2016-01-12' * console.log(dateUtil.getDate(time, 'short', '.')) // '2016.1.12' */ getDate (time: JsDate, type: FormatType = 'long', dateSep: string = '-'): string { if (time) { if (type === 'short' || type === 's') { // short type return this.fixDateTime(time, 'D', 'short', dateSep) } else { // default as long type return this.fixDateTime(time, 'D', 'long', dateSep) } } else { return '' } }, /** * 获取格式化时间 * @author youngbeen * @param { string } time - 可转化为js date类型的时间,字符串等 * @param { string } [type] - 格式化的类型,'short'与's'指代短类型(e.g. 18:02),'long'与'l'指代长类型(e.g. 18:02:10)。默认是长类型 * @return { string } 格式化后的时间字符串或者空字符串 * @example * console.log(dateUtil.getTime()) // '' * @example * let time = 1452592930000 * console.log(dateUtil.getTime(time)) // '18:02:10' * console.log(dateUtil.getTime(time, 'short')) // '18:02' */ getTime (time: JsDate, type: FormatType = 'long'): string { if (time) { if (type === 'short' || type === 's') { // short type return this.fixDateTime(time, 'T', 'short') } else { // default as long type return this.fixDateTime(time, 'T', 'long') } } else { return '' } }, /** * 格式化日期时间 * @author youngbeen * @private * @param { string } time - 可转化为js date类型的时间,字符串等 * @param { string } type - 格式化的类型,'DT'代表日期时间,'D'代表日期,'T'代表时间 * @param { string } subType - 格式化的子类型,'long'代表长类型2016-01-12 18:02:10(DT) | 2016-01-12(D) | 18:02:10(T),'short'代表短类型2016-1-12 18:02:10(DT) | 2016-1-12(D) | 18:02 (T) * @param { string } [dateSep] - 日期的分隔符,默认是'-',用 - 分隔 * @return { string } 格式化后的日期时间字符串或者空字符串 */ fixDateTime (time: JsDate, type: DateType, subType: StrictFormatType, dateSep: string = '-'): string { if (time) { let dateTime: JsDate = '' if (typeof (time) === 'string') { // 字符串日期需要做下特殊处理 // NOTE 为了兼容iOS浏览器,将-变换为/ (iOS浏览器不支持带-的日期格式) dateTime = new Date(time.replace(/-/g, '/')) } else { // Date和number类型的日期 dateTime = new Date(time) } let year: string = dateTime.getFullYear().toString() // e.g. 2016 let month: string = (dateTime.getMonth() + 1).toString() // e.g. 1 or 10 let day: string = dateTime.getDate().toString() // e.g. 2 or 26 let hour: string = dateTime.getHours().toString() // e.g. 8 or 12 let minute: string = dateTime.getMinutes().toString() // e.g. 6 or 48 let second: string = dateTime.getSeconds().toString() // e.g. 2 or 39 // console.log(year, month, day, hour, minute, second) // prepare some strings let monthLong: string = month.length === 2 ? month : ('0' + month) // e.g. 01 or 10 let dayLong: string = day.length === 2 ? day : ('0' + day) // e.g. 02 or 26 let hourLong: string = hour.length === 2 ? hour : ('0' + hour) // e.g. 08 or 12 let minuteLong: string = minute.length === 2 ? minute : ('0' + minute) // e.g. 06 or 48 let secondLong: string = second.length === 2 ? second : ('0' + second) // e.g. 02 or 39 // console.log(monthLong, dayLong, hourLong, minuteLong, secondLong) let dateStr: string = year + dateSep + month + dateSep + day // e.g. 2016-1-12 let dateStrLong: string = year + dateSep + monthLong + dateSep + dayLong // e.g. 2016-01-12 let timeStr: string = hourLong + ':' + minuteLong // e.g. 18:02 let timeStrLong: string = hourLong + ':' + minuteLong + ':' + secondLong // e.g. 18:02:10 // console.log(dateStr, dateStrLong, timeStr, timeStrLong) if (type === 'DT') { // date time return subType === 'short' ? (dateStr + ' ' + timeStrLong) : (dateStrLong + ' ' + timeStrLong) } else if (type === 'D') { // date return subType === 'short' ? dateStr : dateStrLong } else { // time return subType === 'short' ? timeStr : timeStrLong } } else { return '' } } }