nowindxdw
11/2/2017 - 8:15 AM

dateFormatRegex

/*****************************************************************
 * 青岛雨人软件有限公司©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;