scala - 日期工具类

package com.zhangxiaofan.util

import java.sql.Timestamp
import java.text.SimpleDateFormat
import java.util.{Calendar, Date}

import org.apache.commons.lang3.time.FastDateFormat
import org.apache.spark.sql.Column
import org.apache.spark.sql.functions.{lit, to_date}

object DateUtil {
  val sdf = FastDateFormat.getInstance("yyyyMMdd")
  val smf = FastDateFormat.getInstance("yyyyMM")
  val syf = FastDateFormat.getInstance("yyyy")
  val sdf5 = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss")
  val sdf6 = FastDateFormat.getInstance("yyyy-MM-dd")
  val MS_PERDAY = 1000 * 60 * 60 * 24

  /**
    * 获取输入天的前一天时间
    *
    * @param date 输入天
    * @return
    */
  def getBeforeDay(date: Date): Date = {
    val beginDate = Calendar.getInstance();
    beginDate.setTime(date)
    beginDate.add(Calendar.DATE, -1)
    beginDate.getTime
  }

  /**
    * 获取输入天的前一天时间
    *
    * @param date 输入天
    * @return
    */
  def getTheSameDayOfLastMonth(date: Date): Date = {
    val beginDate = Calendar.getInstance();
    beginDate.setTime(date)
    beginDate.add(Calendar.MONTH, -1)
    beginDate.getTime
  }

  /**
    * 获取指定日期的前一天日期
    * 返回 yyyy-mm-dd
    *
    * @param date
    * @return
    */
  def getYesterday(date: Date): String = {
    var dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd")
    var cal: Calendar = Calendar.getInstance()
    cal.setTime(date)
    cal.add(Calendar.DATE, -1)
    var yesterday = dateFormat.format(cal.getTime())
    yesterday
  }

  /**
    * 获取去年的年份
    * @param date
    * @return
    */
  def beforeYear(date: Date): (Int) = {
    val cals: Calendar = Calendar.getInstance();
    cals.setTime(date)
    cals.add(Calendar.YEAR, -1);
    var yearstrs = cals.get(Calendar.YEAR);
    yearstrs
  }

  /**
    * 获取当年的年份
    * @param date
    * @return
    */
  def NowYear(date: Date): (Int) = {
    val cals = Calendar.getInstance();
    cals.setTime(date)
    cals.add(Calendar.YEAR, 0);
    var yearstrs = cals.get(Calendar.YEAR)
    yearstrs
  }

  /**
    * 获取指定日期的月份
    * @param date
    * @return
    */
  def NowMon(date: Date): (Int) = {
    val cals = Calendar.getInstance();
    cals.setTime(date)
    println("cals" + cals)
    cals.add(Calendar.MONTH, 0);
    var monstrs = cals.get(Calendar.MONTH)
    monstrs + 1
  }

  /**
    * 获取指定日期在一月中的第几天
    * @param date
    * @return
    */
  def NowDay(date: Date): (Int) = {
    val cals = Calendar.getInstance();
    cals.setTime(date)
    cals.add(Calendar.DATE, 0);
    var daystrs = cals.get(Calendar.DATE)
    daystrs
  }

  /**
    * 获取当年的第一天,返回类型为yyyy-MM-dd
    * @param date
    * @return
    */
  def getNowMonthStart(date: Date): String = {
    var year = NowYear(date)
    var month = 0
    var period: String = ""
    var cal: Calendar = Calendar.getInstance();
    var df: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    cal.set(Calendar.YEAR, year)
    cal.set(Calendar.MONTH, month);
    cal.set(Calendar.DATE, 1); //设置为1号,当前日期既为本月第一天
    period = df.format(cal.getTime()) + ""
    period
  }

  /**
    * 获取当年的第一天,返回类型为yyyyMMdd
    * @param date
    * @return
    */
  def getNowMonthStart2(date: Date): String = {
    var year = NowYear(date)
    var month = 0
    var period: String = ""
    var cal: Calendar = Calendar.getInstance();
    var df: SimpleDateFormat = new SimpleDateFormat("yyyyMMdd");
    cal.set(Calendar.YEAR, year)
    cal.set(Calendar.MONTH, month);
    cal.set(Calendar.DATE, 1); //设置为1号,当前日期既为本月第一天
    period = df.format(cal.getTime()) + ""
    period
  }

  /**
    * 获取去年的最后一天
    * @param date
    * @return
    */
  def getLastDayOfyear(date: Date): String = {
    var dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    var cal: Calendar = Calendar.getInstance()
    var year = beforeYear(date)
    var month = 11
    //设置年份
    cal.set(Calendar.YEAR, year);
    //设置月份
    cal.set(Calendar.MONTH, month);
    //获取某月最大天数
    val lastDay = cal.getActualMaximum(Calendar.DATE);
    //设置日历中月份的最大天数
    cal.set(Calendar.DAY_OF_MONTH, lastDay);
    //格式化日期
    var lastday = dateFormat.format(cal.getTime())
    lastday
  }

  /**
    * 获取去年的最后一天
    * @param date
    * @return
    */
  def getLastDayOfyearstr(date: Date): String = {
    var dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyyMMdd");
    var cal: Calendar = Calendar.getInstance()
    var year = beforeYear(date)
    var month = 11
    //设置年份
    cal.set(Calendar.YEAR, year);
    //设置月份
    cal.set(Calendar.MONTH, month);
    //获取某月最大天数
    val lastDay = cal.getActualMaximum(Calendar.DATE);
    //设置日历中月份的最大天数
    cal.set(Calendar.DAY_OF_MONTH, lastDay);
    //格式化日期
    var lastday = dateFormat.format(cal.getTime())
    lastday
  }

  /**
    * 获取上个月底最后一天
    * @param date
    * @return
    */
  def getLastDayOfMonth(date: Date): (String) = {
    val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    val cal = Calendar.getInstance();
    cal.setTime(date)
    cal.add(Calendar.MONTH, -1); //设置为上个月的月历
    cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
    var lastday = dateFormat.format(cal.getTime())
    lastday

  }

  /**
    * 获取上个月底最后一天  yyyyMMdd
    * @param date
    * @return
    */
  def getLastDayOfMonthstr(date: Date): (String) = {
    val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyyMMdd");
    val cal = Calendar.getInstance();
    cal.setTime(date)
    cal.add(Calendar.MONTH, -1); //设置为上个月的月历
    cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
    var lastday = dateFormat.format(cal.getTime())
    lastday
  }

  /**
    * 获取上上月的最后一天
    * @param date
    * @return
    */
  def getLastDayOfMonth2(date: Date): (String) = {
    val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    val cal = Calendar.getInstance();
    cal.setTime(date)
    cal.add(Calendar.MONTH, -2); //设置为上个月的月历
    cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
    var lastday = dateFormat.format(cal.getTime())
    lastday
  }

  /**
    * 获取每个月的第一天
    * @param date
    * @return
    */
  def getDayofMonth(date: Date): String = {
    val c = Calendar.getInstance();
    val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    c.setTime(date)
    c.add(Calendar.MONTH, 0);
    c.set(Calendar.DAY_OF_MONTH, 1); //设置为1号,当前日期既为本月第一天
    val day = dateFormat.format(c.getTime());
    day
  }

  /**
    * 获取每个月的第一天
    * @param date
    * @return
    */
  def getDayofMonth2(date: Date): String = {
    val c = Calendar.getInstance();
    val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyyMMdd");
    c.setTime(date)
    c.add(Calendar.MONTH, 0);
    c.set(Calendar.DAY_OF_MONTH, 1); //设置为1号,当前日期既为本月第一天
    val day = dateFormat.format(c.getTime());
    day
  }

  /**
    * 获取一年的天数
    * @param date
    * @return
    */
  def getDaysonYear(date: Date): Int = {
    var instance: Calendar = Calendar.getInstance();
    instance.clear();
    instance.set(DateUtil.NowYear(date), 11, 31); // 设置指定的时间为本年的最后一天
    val DAY_OF_YEAR = instance.get(Calendar.DAY_OF_YEAR); // 获取一年中的第 N 天
    DAY_OF_YEAR
  }

  /**
    * 获取指定日期是一年中的第几天
    * @param date
    * @return
    */
  def getDaysInYear(date: Date): Int = {
    var instance: Calendar = Calendar.getInstance();
    instance.clear();
    instance.set(NowYear(date), NowMon(date) - 1, NowDay(date)); // 设置指定的时间
    val DAY_IN_YEAR = instance.get(Calendar.DAY_OF_YEAR); // 获取一年中的第 N 天
    DAY_IN_YEAR
  }

  /**
    * 结束日期与起始日期的时间差(以天为单位)
    *
    * @example getStartToEndDiffer("20180101","20180401")
    * @param start 起始日期
    * @param end   结束日期
    * @return 时间差
    */
  def getStartToEndDiffer(start: Date, end: Date): Int = {
    ((end.getTime - start.getTime) / MS_PERDAY).toInt
  }

  /**
    *
    * @example add("20180101",90),add("20180101",-90)
    * @param start  起始日期
    * @param dayNum 天数
    * @return
    */
  def add(start: Date, dayNum: Int): Date = {
    val beginDate = Calendar.getInstance();
    beginDate.setTime(start)
    beginDate.add(Calendar.DAY_OF_MONTH, dayNum)
    beginDate.getTime
  }

  /**
    * 返回2个日期之间日期集合(包括起始,结束日期)
    * 起始日期要小于结束日期
    *
    * @param start
    * @param end
    * @return
    */
  def getEveryDayByDate(start: Date, end: Date): Array[Date] = {
    val differDay = getStartToEndDiffer(start, end) + 1
    val arrayDay = new Array[Date](differDay)
    for (i <- 0 until differDay) {
      arrayDay(i) = add(start, i)
    }
    arrayDay
  }

  /**
    * 返回指定年月份的最后一天,返回格式date数据类型
    *
    * @param date 格式yyyyMMdd
    */
  def getLastDateOnMonth(date: Date): Date = {
    val cal = Calendar.getInstance();
    cal.setTime(date)
    cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
    cal.getTime
  }

  /**
    * 返回指定年份的最后一天
    *
    * @param date
    * @return
    */
  def getLastDateOnYear(date: Date): Date = {
    val cal = Calendar.getInstance();
    cal.setTime(date)
    cal.set(Calendar.DAY_OF_YEAR, cal.getActualMaximum(Calendar.DAY_OF_YEAR));
    cal.getTime
  }

  /**
    * 获取指定月份的天数
    *
    * @param date
    * @return
    */
  def getDayNumOnMonth(date: Date): Int = {
    val cal = Calendar.getInstance()
    cal.setTime(date)
    cal.set(Calendar.DATE, 1)
    cal.roll(Calendar.DATE, -1)
    val maxDate = cal.get(Calendar.DATE)
    maxDate
  }

  /**
    * 指定日期的月份第一天
    *
    * @param date
    * @return
    */
  def getFirstDateOnMonth(date: Date): Date = {
    val calendar = Calendar.getInstance()
    calendar.setTime(date)
    calendar.set(Calendar.DAY_OF_MONTH, 1)
    calendar.getTime
  }

  /**
    * 指定年的第一天
    *
    * @param date
    * @return
    */
  def getFirstDateOnYear(date: Date): Date = {
    val calendar = Calendar.getInstance()
    calendar.setTime(date)
    calendar.set(Calendar.DAY_OF_YEAR, 1)
    calendar.getTime
  }

  /**
    * 获取指定日期的上一个月 比如yyyyMMdd
    *
    *
    * @param date yyyyMMdd
    * @return yyyyMM
    */
  def getPreviousMonth(date: Date): Date = {
    val cal = Calendar.getInstance()
    cal.setTime(date)
    // cal.set(Calendar.DAY_OF_MONTH,1)
    cal.add(Calendar.MONTH, -1)
    cal.getTime
  }


  /**
    * 获取指定日期 是星期几
    *
    * @param date
    * @return
    */
  def getDayOfWeekZeroIndex(date: Date): Int = {
    val cal = Calendar.getInstance();
    cal.setTime(date)
    cal.get(Calendar.DAY_OF_WEEK) - 1
  }

  /**
    * 判断输入天是否是月末最后一天
    *
    * @param date 输入天 ,格式"YYYYMMDD"
    * @return
    */
  def isTheEndOfAMonth(date: String): Boolean = {
    val cal = Calendar.getInstance
    cal.set(date.substring(0, 4).toInt, 2, 0)
    val isLeapYear = cal.get(Calendar.DAY_OF_MONTH) match {
      case 28 => false
      case 29 => true
    }

    val isTheEnd = date.substring(4, 8) match {
      case "0131" => true
      case "0228" => !isLeapYear & true
      case "0229" => true
      case "0331" => true
      case "0430" => true
      case "0531" => true
      case "0630" => true
      case "0731" => true
      case "0831" => true
      case "0930" => true
      case "1031" => true
      case "1130" => true
      case "1231" => true
      case _ => false
    }

    isTheEnd
  }

  /**
    * 对时间进行月份加减
    *
    * @param date
    * @param numMonth
    * @return
    */
  def addMonth(date: Date, numMonth: Integer): Date = {
    val cal = Calendar.getInstance();
    cal.setTime(date)
    cal.add(Calendar.MONTH, numMonth)
    cal.getTime
  }

  /**
    * 通用日期加减,年月日 都可以进行加减
    *
    * @param date
    * @param format    日期格式
    * @param num
    * @param dateLevel 与Calendar 的日期类型的常量值对应
    */
  def addDate(date: Date, format: String, num: Integer, dateLevel: Int): Date = {
    val sdff = new SimpleDateFormat(format)
    val cal = Calendar.getInstance()
    cal.setTime(date)
    cal.add(dateLevel, num)
    cal.getTime
  }

  /**
    * 获取当前的时间
    * @return
    */
  def getCurrentTime(): String = {
    val now: Date = new Date()
    val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    val date = dateFormat.format(now)
    date
  }

  /**
    * 日期转yyyyMMdd 格式字符串
    *
    * @param date
    * @return
    */
  def format(date: Date): String = {
    sdf.format(date)
  }

  /**
    * 日期格式化 "yyyy-MM-dd HH:mm:ss"
    *
    * @param date
    * @return
    */
  def etlFormat(date: Date): String = {
    sdf5.format(date)
  }

  /**
    * 返回yyyy-MM-dd 格式
    *
    * @param date
    */
  def etlFormat2(date: Date): String = {
    sdf6.format(date)
  }

  /**
    * 日期转yyyyMM 格式字符串
    *
    * @param date
    * @return
    */
  def formatMon(date: Date): String = {
    smf.format(date)
  }

  /**
    * 日期转yyyy 格式字符串
    *
    * @param date
    * @return
    */
  def formatYear(date: Date): String = {
    syf.format(date)
  }

  /**
    * 日期格式化通用格式
    *
    * @param date
    * @param toFormat
    * @return
    */
  def format(date: Date, toFormat: String): String = {
    new SimpleDateFormat(toFormat).format(date)
  }

  /**
    * yyyyMMdd 转Date
    *
    * @param date
    * @return
    */
  def parse(date: String): Date = {
    sdf.parse(date)
  }

  /**
    * yyyyMM 转Date
    *
    * @param date
    * @return
    */
  def parseMon(date: String): Date = {
    smf.parse(date)
  }

  /**
    * yyyy 转Date
    *
    * @param date
    * @return
    */
  def parseYear(date: String): Date = {
    syf.parse(date)
  }

  def getTimestampByDate(date: Date): Timestamp = {
    new Timestamp(date.getTime)
  }

  /**
    * 判断是否是季度末,结合月底最后一天里调用该方法可判断是否是季度末最后一天
    *
    * @param date 天日期
    * @return
    */
  def isEndOfQuarter(date: Date): Boolean = {
    val dateStr = format(date)
    if (isTheEndOfAMonth(dateStr)) {
      val month = dateStr.substring(4, 6).toInt
      month % 3 == 0
    } else {
      false
    }
  }

  /**
    * 是否是周四
    *
    * @param date 天日期
    * @return
    */
  def isThuOfWeek(date: Date): Boolean = {
    getDayOfWeekZeroIndex(date) == 4
  }

  /**
    * 判断是否是周五
    *
    * @param date
    * @return
    */
  def isFriOfWeek(date: Date): Boolean = {
    getDayOfWeekZeroIndex(date) == 5
  }

  /**
    * 是否是周一
    *
    * @param date 天日期
    * @return
    */
  def isMonOfWeek(date: Date): Boolean = {
    getDayOfWeekZeroIndex(date) == 1
  }

  def isEndOfWeek(date: Date): Boolean = {
    getDayOfWeekZeroIndex(date) == 0
  }

  /**
    * 返回当季末日期
    *
    * @param date
    * @return
    */
  def getCurrentQuarterDateEnd(date: Date): Date = {
    val calendar: Calendar = Calendar.getInstance()
    calendar.setTime(date)
    val month: Int = calendar.get(Calendar.MONTH)
    val quarter = month / 3 + 1
    var endMonth = 3
    if (quarter == 2) {
      endMonth = 6
    } else if (quarter == 3) {
      endMonth = 9
    } else if (quarter == 4) {
      endMonth = 12
    }
    calendar.set(Calendar.MONTH, endMonth - 1)
    val lastDay: Int = calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
    calendar.set(Calendar.DAY_OF_MONTH, lastDay)
    calendar.getTime()
  }


  /**
    * date: 20180101  转 string 格式:yyyy-MM-dd
    *
    * @param date
    * @num 当前时间的增减天数
    * @return
    */
  def passedDay(date: Date, num: Int): String = {
    etlFormat2(DateUtil.add(date, num))
  }


  /**
    * Date转 ETL_DATE 固定格式为yyyy-MM-dd
    *
    * @param date
    * @num 当前时间的增减天数
    * @return
    */
  def getETL_DATE(date: Date, num: Int = 0): Column = {
    to_date(lit(etlFormat2(DateUtil.add(date, num))))
  }

  /**
    * 计算两个日期相差年数
    * @param startDate
    * @param endDate
    * @return
    */
  def yearDateDiff(startDate: Date, endDate: Date): Int = {
    val calBegin: Calendar = Calendar.getInstance(); //获取日历实例
    val calEnd: Calendar = Calendar.getInstance();
    calBegin.setTime(startDate); //字符串按照指定格式转化为日期
    calEnd.setTime(endDate);
    calEnd.get(Calendar.YEAR) - calBegin.get(Calendar.YEAR);
  }

  def main(args: Array[String]): Unit = {
    //    println(getPreviousMonth("20181202"))
    //    println(isTheEndOfAMonth("20000228"))
    println(getFirstDateOnMonth(sdf.parse("20171120")))
    println(getStartToEndDiffer(DateUtil.parse("20171120"), DateUtil.parse("20171123")))
    println(DateUtil.getEveryDayByDate(DateUtil.parse("20171120"), DateUtil.parse("20171123")).length)
    // println(add(DateUtil.parse("20171120"),1))

    println(sdf.format(new Date(1530547200 * 1000L)))
    println(sdf.format(new Date(20181120)))

    println(DateUtil.format(getLastDateOnYear(new Date())))
    println(DateUtil.format(getFirstDateOnYear(new Date())))
    println(formatMon(addMonth(parse("20171231"), -3)))
    println(parseMon("201711").before(parseMon("201711")))
    println(format(DateUtil.add(parse("20171021"), -10)))
    println(getBeforeDay(parse("20171021")))
    println(getBeforeDay(parse("20170101")))

    println(getTheSameDayOfLastMonth(parse("20170101")))
    println(getTheSameDayOfLastMonth(parse("20170330")))

    println(getDayNumOnMonth(new Date()))


    val date = new Date()

    println("指定的日期" + date)
    println("获取指定日期的前一天日期" + DateUtil.getYesterday(date))
    println("获取去年的年份" + DateUtil.beforeYear(date))
    println("获取当年的年份" + DateUtil.NowYear(date))
    println("获取当年的第一天" + DateUtil.getNowMonthStart(date))
    println("获取去年的最后一天" + DateUtil.getLastDayOfyear(date))
    println("获取上个月底最后一天" + DateUtil.getLastDayOfMonth(date))
    println("获取上上月的最后一天" + DateUtil.getLastDayOfMonth2(date))
    println("获取每个月的一天" + DateUtil.getDayofMonth(date))
  }

}

 

posted @ 2021-01-04 14:35  快乐的张小凡  阅读(1034)  评论(0编辑  收藏  举报