@diyaner/ding
Version:
dingiyan常用ts/js工具
448 lines • 15 kB
JavaScript
"use strict";
/*
* @copyright: Huang Ding
* @Author: ding-cx
* @Date: 2021-01-13 18:12:46
* @LastEditors: ding
* @LastEditTime: 2022-08-20 10:21:17
* @Description: 时间日期处理工具
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.calcMinsNumber = exports.monthSplitWeek = exports.findWeekDate = exports.DateFormat = void 0;
/**
* [DateFormat 日期时间格式化类]
* @param {string | Date} datestr [类实例化时接收一个日期时间字符串或者日期对象]
* 如果该字符串无法被new Date解析,则以当前系统时间创建。
*/
class DateFormat {
/**
* 构造函数,初始化类为一个对象实例时调用的
* Creates an instance of DateFormat.
* - 如果传入参数不能被new Date将内置默认使用当前时间new Date,请自行先判断是否是一个可new Date的参数值。
* @param {string | number | Date} datestr 接收一个日期字符串/时间戳或日期对象。
* @memberof DateFormat
*
*/
constructor(datestr) {
/**
*格式化日期的字符串。内置的。
*
* @memberof DateFormat
*/
this.defaultFormatStr = "yyyy-MM-dd hh:mm:ss";
/**
*格式化后保存的日期字符串
*
* @memberof DateFormat
*/
this.formatdate = "";
if (datestr instanceof Date) {
this.datetime = new Date(datestr.getTime());
}
else {
// 处理苹果浏览器兼容性问题
let milliseconds = 0;
if (typeof datestr === "string") {
const [date, ms] = datestr.split(".");
if (!date)
throw new Error(`DateFormat: your Date [${datestr}] is Invalid Date!`);
datestr = date.replace(/-/g, "/").replace("T", " ");
milliseconds = Number(ms);
}
// 传入非undefined null的值都将尝试new Date
const theDate = datestr != undefined ? new Date(datestr) : new Date();
if (theDate.toString() === "Invalid Date")
throw new Error(`DateFormat: your Date [${datestr}] is Invalid Date!`);
!!milliseconds && theDate.setMilliseconds(milliseconds);
this.datetime = theDate;
}
this.extract();
this.format();
}
/**
*提取函数,提取日期对象上的年月日时间等数据
*
* @return {*}
* @memberof DateFormat
*/
extract() {
const dateObj = this.datetime;
this.year = dateObj.getFullYear();
this.month = Number(dateObj.getMonth());
this.date = dateObj.getDate();
this.week = dateObj.getDay();
this.hour = dateObj.getHours();
this.seconds = dateObj.getSeconds();
this.minutes = dateObj.getMinutes();
this.milliseconds = dateObj.getMilliseconds();
this.timestamp = dateObj.getTime();
return this;
}
/** 获取时间戳 */
getTime() {
return this.datetime.getTime();
}
/** 增减日*/
addDate(num = 1) {
this.add("D", num);
return this;
}
/**
* 增减月
*
* @param {number} [num=1]
* @return {*}
* @memberof DateFormat
*/
addMonth(num = 1) {
this.add("M", num);
return this;
}
/** 增减年*/
addYear(num = 1) {
this.add("Y", num);
return this;
}
/** 增减时*/
addHour(num = 1) {
this.add("H", num);
return this;
}
/** 增减分钟 */
addMinutes(num = 1) {
return this.add("MIN", num);
}
/** 增减秒 */
addSeconds(num = 1) {
return this.add("S", num);
}
/** 增减毫秒 */
addMilliseconds(num = 1) {
return this.add("MS", num);
}
/** 增减周 */
addWeek(num = 1) {
return this.add("WEEK", num);
}
/** add 方法 根据opt参数决定更改哪一个时间,是具体的add方法调用的。*/
add(opt, num = 1) {
if (num === 0)
return this;
opt = opt.toUpperCase();
//只有当num为非零数值时才会修改addnum增量,否则addnum都是默认1
if (typeof num !== "number") {
throw new Error("the second param num is require number.");
}
let addnum = num;
switch (opt) {
case "Y":
this.datetime.setFullYear(this.year + addnum);
break;
case "M":
this.datetime.setMonth(this.month + addnum);
break;
case "D":
this.datetime.setDate(this.date + addnum);
break;
case "H":
this.datetime.setHours(this.hour + addnum);
break;
case "MIN":
this.datetime.setMinutes(this.minutes + addnum);
break;
case "S":
this.datetime.setSeconds(this.seconds + addnum);
break;
case "MS":
this.datetime.setMilliseconds(this.milliseconds + addnum);
break;
case "WEEK":
this.datetime.setDate(this.date + addnum * 7);
break;
}
this.extract();
return this;
}
/** 替换默认的格式化字符串方法*/
setDefaultFormatStr(str) {
this.defaultFormatStr = str;
}
/**
*日期格式化为一个字符串
*
* @param {String} fmt_ 格式化字符串 yyyy-MM-dd hh:mm:ss
* @return {string} 日期字符串 2021-12-12 10:12:12
*/
format(fmt_) {
const date = this.datetime;
let fmt = fmt_ || this.defaultFormatStr;
const formatedString = DateFormat.formatDate(date, fmt);
this.formatdate = formatedString;
return formatedString;
}
/** 格式化一个年月日,固定格式 "yyyy-MM-dd"*/
formatYmd() {
return this.format("yyyy-MM-dd");
}
setTimeTo(hour, mins, sec) {
this.datetime.setHours(hour, mins, sec, 0);
this.extract();
return this;
}
/** 将时间设置为 00:00:00 */
setTimeToDayStart() {
return this.setTimeTo(0, 0, 0);
}
/** 将时间设置为 23:59:59 */
setTimeToDayEnd() {
return this.setTimeTo(23, 59, 59);
}
setDateTo(date) {
this.datetime.setDate(date);
this.extract();
return this;
}
/**
* 设置一个日期到当月第一天
* - 不关注时间部分
*/
setDateToMonthFirst() {
return this.setDateTo(1);
}
/**
* 设置一个时间到当月最后一天
* - 不关注时间部分
*/
setDateToMonthEnd() {
const a = this.addMonth(1).setDateToMonthFirst().addDate(-1);
return a;
}
/**
* 设置一个时间到当年第一天
* - 不关注时间部分
*/
setToYearFirstDay() {
this.datetime.setMonth(0, 1);
this.extract();
return this;
}
/**
* 设置一个时间到当年最后一天
* - 不关注时间部分
*/
setToYearEndDay() {
this.datetime.setMonth(11, 31);
this.extract();
return this;
}
/**
* 计算一个时间分钟的当日分钟数
* 如 2022-01-01 08:00:00 -> 08:00 -> 8 * 60 + 0 -> 480
* @return {number} 返回分钟数
*/
calcMinsNumber() {
const dateStr = this.format("hh:mm");
return calcMinsNumber(dateStr);
}
/**
* 计算日期所在的月份的第一天和最后一天
*
* @param {boolean} [isReturnFormatStr=true] 是否返回格式化后的字符串日期 默认是
* @return {*} 形如:["2022-10-01","2022-10-31"] 或者[new Date('2022-10-01 00:00:00'),new Date('2022-10-31 23:59:59')]
* @memberof DateFormat
*/
currentMonth(isReturnFormatStr) {
isReturnFormatStr = isReturnFormatStr === undefined ? true : isReturnFormatStr;
const start = this.format(`yyyy-MM-01`);
const end = this.clone()
.addMonth(1)
.setDateToMonthFirst()
.addDate(-1)
.format(`yyyy-MM-dd`);
if (isReturnFormatStr) {
return [start, end];
}
return [new Date(start + " 00:00:00"), new Date(end + " 23:59:59")];
}
/** DateFormat的方法都是单实例操作,返回实例本身,若遇到需要新实例时,可以调用clone方法返回新实例 */
clone() {
const newInstance = new DateFormat(this.format("yyyy-MM-dd hh:mm:ss.SSS"));
newInstance.setDefaultFormatStr(this.defaultFormatStr);
return newInstance;
}
/** 下一个星期几
* - 周日到周六为0-6
*/
nextWeekDay(weekDay) {
const diff = 7 - this.week + weekDay;
return this.addDate(diff);
}
/**
* 下一个周一
*/
nextMonday() {
return this.nextWeekDay(1);
}
/** 下一个月的第一天,时间为00:00:00
*/
nextMonthFirstDay() {
return this.addMonth(1).setDateToMonthFirst().setTimeToDayStart();
}
/**
* 静态方法,日期格式化为一个字符串
*/
static formatDate(date, fmtString = "yyyy-MM-dd hh:mm:ss") {
let fmt = fmtString;
var o = {
"M+": date.getMonth() + 1, //月份
"d+": date.getDate(), //日
"h+": date.getHours(), //小时
"H+": date.getHours(), //小时
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
};
/** 年匹配 */
const yReg = /(y+)|(Y+)/;
if (yReg.test(fmt)) {
fmt = fmt.replace(yReg, (match) => {
return date
.getFullYear()
.toString()
.substring(4 - match.length);
});
}
// 毫秒匹配
const Sreg = /(S+)/;
if (Sreg.test(fmt)) {
fmt = fmt.replace(Sreg, (match) => {
const str = date.getMilliseconds().toString().padStart(3, "0");
const len = match.length >= 3 ? 3 : match.length;
return str.substring(0, len);
});
}
for (var k in o) {
const nreg = new RegExp("(" + k + ")");
if (nreg.test(fmt)) {
const ok = o[k];
fmt = fmt.replace(nreg, (match) => {
const len = match.length >= 2 ? 2 : 1;
return ok.toString().padStart(len, "0");
});
// fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
}
}
return fmt;
}
/**
* 计算两个日期的差值
*
* @static
* @param {(number | Date)} date1 开始日期 较小的日期
* @param {(number | Date)} date2 结束日期 较大的日期
* @return {{days: number;hours: number;minutes: number; seconds: number}}
* @memberof DateFormat
*/
static calcTwoDateDiffer(date1, date2) {
date1 = date1 instanceof Date ? date1.getTime() : date1;
date2 = date2 instanceof Date ? date2.getTime() : date2;
var date3 = date2 - date1;
var days = Math.floor(date3 / (24 * 3600 * 1000));
var leave1 = date3 % (24 * 3600 * 1000); //计算天数后剩余的毫秒数
var hours = Math.floor(leave1 / (3600 * 1000));
var leave2 = leave1 % (3600 * 1000); //计算小时数后剩余的毫秒数
var minutes = Math.floor(leave2 / (60 * 1000));
var leave3 = leave2 % (60 * 1000); //计算分钟数后剩余的毫秒数
var seconds = Math.round(leave3 / 1000);
return {
days: days,
hours: hours,
minutes: minutes,
seconds: seconds,
};
}
/** 静态属性,实例化自身DateFormat类并返回 */
static init(date = new Date()) {
return new DateFormat(date);
}
} //DateFormat类 end
exports.DateFormat = DateFormat;
DateFormat.findWeekDate = findWeekDate;
DateFormat.monthSplitWeek = monthSplitWeek;
exports.default = DateFormat;
/**
*寻找一个日期所处的一周的周几的Date
*
* @export
* @param {Date} day 一个日期
* @param {0} week 需要找这周的周几0-6 周日-周六
*/
function findWeekDate(date, week = 0) {
const day = date.getDay();
const reduce = week - day;
date.setDate(date.getDate() + reduce);
return date;
}
exports.findWeekDate = findWeekDate;
/**
*把一个月按周分割时间段。以周一为起始
*
* @export
* @param {Date} date 传入一个日期
* @param {boolean} [isFirstDayStart=true] 以每月1日所在周作为起始周,若false则以每月第一个周一为始
*/
function monthSplitWeek(date, isFirstDayStart = false) {
const y = date.getFullYear();
const m = Number(date.getMonth()) + 1;
const monthStartDate = new Date(`${y}-${m}-01 00:00:00`);
const monthEndDate = m === 12 ? new Date(`${y + 1}-01-01 00:00:00`) : new Date(`${y}-${m + 1}-01 00:00:00`);
// console.log(monthEndDate);
monthEndDate.setDate(0);
// console.log(monthEndDate);
// console.log(monthStartDate);
const everyWeekMondaySunday = [];
while (everyWeekMondaySunday.length < 1) {
if (monthStartDate.getDay() === 1) {
everyWeekMondaySunday.push([monthStartDate.toLocaleDateString()]);
}
else {
monthStartDate.setDate(monthStartDate.getDate() + 1);
}
}
while (Number(monthStartDate.getMonth()) === m - 1) {
monthStartDate.setDate(monthStartDate.getDate() + 6);
everyWeekMondaySunday[everyWeekMondaySunday.length - 1].push(monthStartDate.toLocaleDateString());
monthStartDate.setDate(monthStartDate.getDate() + 1);
if (Number(monthStartDate.getMonth()) === m - 1) {
everyWeekMondaySunday.push([monthStartDate.toLocaleDateString()]);
}
}
// return res;
return everyWeekMondaySunday;
}
exports.monthSplitWeek = monthSplitWeek;
/**
* 计算一天的某个分钟时间的分钟数
* - 如 12:10 = 12 * 60 + 10 = 730
*
* @export
* @param {string} minStr 时间分钟 形如 09:10
* @return {number} 分钟数
*/
function calcMinsNumber(minStr) {
const arr = minStr.trim().split(":");
if (arr.length < 2) {
throw new Error(`the minStr must typeing hours:minute. like 05:09 means 5:9 a.m`);
}
const hour = Number(arr[0]);
const mins = Number(arr[1]);
if (Number.isNaN(hour)) {
throw new Error(`the hour part is not Number, minStr like 01:00`);
}
if (Number.isNaN(mins)) {
throw new Error(`the minute part is not Number, minStr like 01:00`);
}
return hour * 60 + mins;
}
exports.calcMinsNumber = calcMinsNumber;
//# sourceMappingURL=DateFormat.js.map