/*****************************************************************
* 青岛雨人软件有限公司©2016版权所有
*
* 本软件之所有(包括但不限于)源代码、设计图、效果图、动画、日志、
* 脚本、数据库、文档均为青岛雨人软件或其附属子公司所有。任何组织
* 或者个人,未经青岛雨人软件书面授权,不得复制、使用、修改、分发、
* 公布本软件的任何部分。青岛雨人软件有限公司保留对任何违反本声明
* 的组织和个人采取法律手段维护合法权益的权利。
*****************************************************************/
'use strict';
const moment = require('moment');
const _ = require('lodash');
//yyyy.xx格式
const divideDateFormatRegex = /^\d{4}\.\d{2}$/;
/**
* 增加
* @param dateTime
* @param number
* @param unit
* @param format
* @return {*}
*/
function add(dateTime, number, unit, format) {
let resultTime = moment(dateTime).add(number, unit);
if (format) {
resultTime = resultTime.format(format)
}
return resultTime
}
/**
* 减少
* @param dateTime
* @param number
* @param unit
* @param format
* @return {*}
*/
function subtract(dateTime, number, unit, format) {
let resultTime = moment(dateTime).subtract(number, unit);
if (format) {
resultTime = resultTime.format(format)
}
return resultTime
}
/**
* 获取按特定时间单位分组的时间表
* @param startDate
* @param endDate
* @param unit
* @param format
* @return {Array}
*/
function getDurationArray(startDate, endDate, unit, format) {
let durationArray = [];
let diffCount = dateFormat.diff(startDate, endDate, unit);
for (let i = 0; i < diffCount; i++) {
let formatDate = dateFormat.add(startDate, i, unit);
//处理上一年最后一周
if (unit === dateFormat.week && formatDate.month() === 0) {
let formatDateSplit = formatDate.format(format).split('.');
let week = formatDateSplit[1];
if (week > 50) {
let year = formatDateSplit[0] - 1;
formatDate = year + '.' + week;
} else {
formatDate = formatDate.format(format)
}
} else {
formatDate = formatDate.format(format)
}
durationArray.push(formatDate)
}
return durationArray
}
function getLimitDayArray(dateArray, unit, method, startDate, endDate) {
let resultDateArray = _.map(dateArray, function (itemDate) {
let resultItem;
switch (unit) {
case dateFormat.year:
let dateTime = dateFormat.moment().year(itemDate).format(dateFormat.YMD);
resultItem = dateFormat[method](dateTime, dateFormat.year, dateFormat.YMD);
break;
case dateFormat.month:
let monthDateTime;
if (divideDateFormatRegex.test(itemDate)) {
let yearMonthArr = itemDate.split('.');
//month范围为0~11
monthDateTime = dateFormat.moment().year(+yearMonthArr[0]).month(yearMonthArr[1]-1).format(dateFormat.YMD);
} else {
monthDateTime = dateFormat.format(itemDate, dateFormat.YMD)
}
resultItem = dateFormat[method](monthDateTime, dateFormat.month, dateFormat.YMD);
break;
case dateFormat.week:
let yearWeekArr = itemDate.split('.');
let weekDateTime = dateFormat.moment().year(yearWeekArr[0]).isoWeek(yearWeekArr[1]).format(dateFormat.YMD);
resultItem = dateFormat[method](weekDateTime, dateFormat.isoWeek, dateFormat.YMD);
break;
default:
resultItem = itemDate;
break;
}
return resultItem;
});
//如果最小一天小于起始时间,则将最小一天替换为起始时间
if (startDate && dateFormat.isBefore(resultDateArray[0], startDate)) {
resultDateArray[0] = dateFormat.format(startDate, dateFormat.YMD)
}
let lastIndex = resultDateArray.length - 1;
//如果最后一天比截止时间晚,则将最后一天设置为截止时间
if (endDate && dateFormat.isBefore(endDate, resultDateArray[lastIndex])) {
resultDateArray[lastIndex] = dateFormat.format(endDate, dateFormat.YMD)
}
return resultDateArray;
}
function getFirstDayArray(dateArray, unit, startDate, endDate) {
return getLimitDayArray(dateArray, unit, 'startOf', startDate, endDate)
}
function getEndDayArray(dateArray, unit, startDate, endDate) {
return getLimitDayArray(dateArray, unit, 'endOf', startDate, endDate)
}
const dateFormat = {
Y: 'Y',
M: 'M',
D: 'D',
d: 'd',
H: 'H',
h: 'h',
m: 'm',
s: 's',
S: 'S',
YY: 'YYYY',
MM: 'MM',
DD: 'DD',
dd: 'dd',
HH: 'HH',
hh: 'hh',
mm: 'mm',
ss: 'ss',
SSS: 'SSS',
X: 'X',
Y_W: 'YYYY.WW',
YM: 'YYYY-MM',
YMD: 'YYYY-MM-DD',
YMDHM: 'YYYY-MM-DD HH:mm',
YMDhM: 'YYYY-MM-DD hh:mm',
YMDHMS: 'YYYY-MM-DD HH:mm:ss',
YMDhMS: 'YYYY-MM-DD hh:mm:ss',
YMDHMSS: 'YYYY-MM-DD hh:mm:ss SSS',
Y_M: 'YYYY.MM',
year: 'year',
month: 'month',
date: 'date',
hour: 'hour',
minute: 'minute',
second: 'second',
millisecond: 'millisecond',
ms: 'ms',
day: 'day',
week: 'week',
isoWeek: 'isoWeek',
months: 'months',
years: 'years',
days: 'days',
add: add,
moment: (dateTime) => dateTime ? moment(dateTime) : moment(),
subtract: subtract,
subtractYear: (dateTime, number, format) => subtract(dateTime, number, dateFormat.years, format),
subtractMonth: (dateTime, number, format) => subtract(dateTime, number, dateFormat.months, format),
subtractDay: (dateTime, number, format) => subtract(dateTime, number, dateFormat.days, format),
addYear: (dateTime, number, format) => add(dateTime, number, dateFormat.years, format),
addDays: (dateTime, number, format) => add(dateTime, number, dateFormat.days, format),
addMinute: (dateTime, number, format) => add(dateTime, number, dateFormat.minute, format),
format: (dateTime, regex) => moment(dateTime).format(regex),
formatCurrent: (regex) => moment().format(regex),
isBefore: (time1, time2) => moment(time1).isBefore(time2),
getDay: (dateTime) => moment(dateTime).get(dateFormat.date),
getHour: (dateTime) => moment(dateTime).get(dateFormat.hour),
getMinute: (dateTime) => moment(dateTime).get(dateFormat.minute),
getSecond: (dateTime) => moment(dateTime).get(dateFormat.second),
getYear: (dateTime) => moment(dateTime).get(dateFormat.years),
startOf: (dateTime, regex, format) => {
let newDateTime = moment(dateTime).startOf(regex);
return format ? newDateTime.format(format) : newDateTime;
},
endOf: (dateTime, regex, format) => {
let newDateTime = moment(dateTime).endOf(regex);
return format ? newDateTime.format(format) : newDateTime;
},
getDurationArray: getDurationArray,
getFirstDayArray: getFirstDayArray,
getEndDayArray: getEndDayArray,
diff: (firstTime, lastTime, unit) => {
let first = moment(firstTime);
let last = moment(lastTime);
let resultDiff = last.diff(first);
let divide = 0;
switch (unit) {
case dateFormat.second:
divide = 1000;
resultDiff = resultDiff / divide + 1;
break;
case dateFormat.minute:
divide = 1000 * 60;
resultDiff = resultDiff / divide + (dateFormat.moment(firstTime).second() <= dateFormat.moment(lastTime).second() ? 1 : 2);
break;
case dateFormat.hour:
divide = 1000 * 60 * 60;
//小时 23点与第二天1时差2天,时差<24小时
resultDiff = resultDiff / divide + (dateFormat.moment(firstTime).minute() <= dateFormat.moment(lastTime).minute() ? 1 : 2);
break;
case dateFormat.day:
divide = 1000 * 60 * 60 * 24;
resultDiff = resultDiff / divide + (dateFormat.moment(firstTime).hour() <= dateFormat.moment(lastTime).hour() ? 1 : 2);
break;
case dateFormat.week:
divide = 1000 * 60 * 60 * 24 * 7;
resultDiff = resultDiff / divide + (dateFormat.moment(firstTime).isoWeekday() <= dateFormat.moment(lastTime).isoWeekday() ? 1 : 2);
break;
case dateFormat.month:
let yearDiff = last.year() - first.year();
//同年
let monthDiff = 0;
if (yearDiff == 0) {
monthDiff = last.month() - first.month() + 1;
resultDiff = monthDiff;
} else {
//month 0~11
monthDiff = last.month() + 1 + 12 - first.month();
resultDiff = (yearDiff - 1) * 12 + monthDiff;
}
break;
case dateFormat.year:
resultDiff = last.year() - first.year() + 1;
break;
}
return parseInt(resultDiff)
},
formatToDate: (dateTime) => /^\d{4}-\d{2}-\d{2}$/.test(dateTime) ? dateTime : dateFormat.format(dateTime, dateFormat.YMD),
formatToDateArray: (startTime, endTime) => {
let array = [];
let startDate = dateFormat.formatToDate(startTime);
let endDate = dateFormat.formatToDate(endTime);
array.push(startDate);
while (startDate < endDate) {
startDate = dateFormat.addDays(startDate, 1, dateFormat.YMD);
array.push(startDate);
}
return array
}
};
module.exports = dateFormat;