package com.xxx.base.modules.oa.service.impl;
import com.xxx.base.common.utils.DateUtils;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* 一个时间工具类,用于封装时间类型时间和字符串类型时间的处理
* 包括:字符串和时间的相互转换(这个去用DateUtils)。时间的加减计算
* 考虑到以后可能要合并代码到xxx,容易忘记,故工具类先扔在service层
*/
public class DateStrUtils {
/** 时间格式(yyyy-MM-dd) */
public final static String PATTERN_yMd = "yyyy-MM-dd";
/** 时间格式(yyyy-MM-dd HH:mm:ss) */
public final static String PATTERN_yMdHms = "yyyy-MM-dd HH:mm:ss";
/** 时间格式( HH:mm ) */
public final static String PATTERN_Hm = "HH:mm";
/**
* 获取现在日期时间的字符串
* 时间格式(yyyy-MM-dd HH:mm:ss)
* @return String 比如, 2020-03-18 13:54:02
*/
public static String getCurrentTimeStr(){
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String timeStr2 = sf.format(date);
return timeStr2;
}
/**
* 获取当前日期
* 时间格式(yyyy-MM-dd)
* @return String 比如,2020-03-20
*/
public static String getCurrentDayStr() {
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
String timeStr2 = sf.format(date);
return timeStr2;
}
/**
*时间(String)加减"分钟"并返回。
* (目前只考虑加减"分钟",以后扩展)
* @param originalTime 字符串类型时间, HH:mm 格式(以后扩展)
* @param minutes 加减分钟
* @return String HH:mm (以后扩展。现在只是为了计算“时间段”)
* pattern : DateStrUtils.PATTERN_Hm
* 比如,输入 ("08:00",-10,DateStrUtils.PATTERN_Hm) 输出 "07:50"
*/
public static String addOrSubMinutesTime(String originalTime,Integer minutes,String pattern){
// 用java封装的时间处理,免去码农自己考虑满60进位的蛋疼
//String stringStartTime="2020-03-20 9:53";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
Date dateStartTime=null;
Date dateStartTime2=null;
try {
//java中:字符串转换为时间类型
dateStartTime =sdf.parse(originalTime);
} catch (ParseException e) {
e.printStackTrace();
}
//工厂方法,创建Calendar对象
Calendar cal=Calendar.getInstance();
//Date转换为Calendar,以便可以直接调用Calendar已写好了的时间加减方法,避免自己手动写时间加减而需要一堆if判断(存在跨小时跨天跨周等蛋疼if考虑)而丑化项目代码
if(dateStartTime!=null){cal.setTime(dateStartTime);}
cal.add(Calendar.MINUTE,minutes);
//sdf.format()入参必须是Date类型,否则抛异常
Date dateDealTime=cal.getTime();
return sdf.format(dateDealTime);
}
/**
* 时间(String类型,yyyy-MM-dd HH:mm:ss)处理,获取时分(String类型,HH:mm)
* 比如,输入 2020-04-02 03:00:00 输出 3:00
*/
public static String getHM(String time){
//不足两位的前补0
String h = String.format("%02d", getHour(time)); //不足位数补"0"
String m = String.format("%02d",getMinute(time));
return h+":"+m;
}
/**
* 比较两个时间(String 类型)的大小,如果前者比后者早,则返回true,晚则返回false。相等,也返回false
* @param time1
* @param time2
* @param pattern 日期格式 如: HH:mm
* @return
* @throws ParseException
* * 比如,HH:mm格式的比较,10:01,10:02,return true
*/
public static boolean compareIsBefore(String time1,String time2,String pattern) throws ParseException {
//如果想比较日期则写成"yyyy-MM-dd"就可以了
SimpleDateFormat sdf=new SimpleDateFormat(pattern);
//将字符串形式的时间转化为Date类型的时间
Date a=sdf.parse(time1);
Date b=sdf.parse(time2);
//Date类的一个方法,如果a早于b返回true,否则返回false
if(a.before(b)) {
return true;
} else {
return false;
}
}
/**
* 时间和字符串相互转换(略。这个用项目里DateUtils工具类即可)
*
*/
//main测试
public static void main(String[] args) throws ParseException {
// String hm=addOrSubMinutesTime("9:53",8);
// System.out.println("加减几分钟后的时间,格式化后展示--"+hm);
// System.out.println(compareIsBefore("7:01","8:01",DateStrUtils.PATTERN_Hm));
// System.out.println("输出时:" + getHour("2019-1-21 13:06:06"));
// System.out.println("输出分:" + getMinute("2019-1-21 13:06:06"));
// System.out.println("输出时:" + getHour("2019-1-21 6:7:06"));
// System.out.println("输出分:" + getMinute("2019-1-21 8:9:06"));
// System.out.println(compareIsBefore("2020-04-02 2:13:00","2020-04-02 03:13:00",DateStrUtils.PATTERN_yMdHms));
String s=getHM("2020-04-02 03:00:00");
System.out.println(s); // 3:0
String hm=addOrSubMinutesTime(s,-10,DateStrUtils.PATTERN_Hm);
System.out.println(hm); // 02:50
}
//---------------------加班ing-------------------------
/**
* 处理时间字符串,得到时,分,秒
*/
public static Date parseTimeString2Date(String timeString) {
if ((timeString == null) || ("".equals(timeString))) {
return null;
}
Date date = null;
DateFormat dateFormat = new SimpleDateFormat(DateStrUtils.PATTERN_yMdHms);
try {
date = new Date(dateFormat.parse(timeString).getTime());
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
public static String convertDate2String(Date date, String pattern) {
if (date == null) {
return null;
}
DateFormat dateFormat = new SimpleDateFormat(pattern);
return dateFormat.format(date);
}
public static int getYear(String timeString) {
String timeStr = convertDate2String(parseTimeString2Date(timeString), DateStrUtils.PATTERN_yMdHms);
return Integer.parseInt(timeStr.substring(0, 4));
}
public static int getMonth(String timeString) {
String timeStr = convertDate2String(parseTimeString2Date(timeString), DateStrUtils.PATTERN_yMdHms);
return Integer.parseInt(timeStr.substring(5, 7));
}
public static int getDay(String timeString) {
String timeStr = convertDate2String(parseTimeString2Date(timeString), DateStrUtils.PATTERN_yMdHms);
return Integer.parseInt(timeStr.substring(8, 10));
}
public static int getHour(String timeString) {
String timeStr = convertDate2String(parseTimeString2Date(timeString), DateStrUtils.PATTERN_yMdHms);
return Integer.parseInt(timeStr.substring(11, 13));
}
public static int getMinute(String timeString) {
String timeStr = convertDate2String(parseTimeString2Date(timeString), DateStrUtils.PATTERN_yMdHms);
return Integer.parseInt(timeStr.substring(14, 16));
}
public static int getSecond(String timeString) {
String timeStr = convertDate2String(parseTimeString2Date(timeString), DateStrUtils.PATTERN_yMdHms);
return Integer.parseInt(timeStr.substring(17, 19));
}
/*
save时,传参:
t: 1585824106468 //忽略
day: "2020-04-02"
activFullTime: "2020-04-02 03:00 - 10:00"
activTheme: "sssss"
activStartTime: "2020-04-02 03:00:00"
activEndTime: "2020-04-02 10:00:00"
restStartTime: "2020-04-02 04:00:00"
restEndTime: "2020-04-02 06:00:00"
cutNum: 1
cutStageVal: 20
totalNum: 15
address: ""
descr: ""
*/
/**
* 校验两个时间段是否有重叠
*/
public static int timeIsJoin(String dateStr1_1, String dateStr1_2, String dateStr2_1, String dateStr2_2) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date s1 = sdf.parse(dateStr1_1);
Date e1 = sdf.parse(dateStr1_2);
Date s2 = sdf.parse(dateStr2_1);
Date e2 = sdf.parse(dateStr2_2);
long ss1 = s1.getTime();
long ee1 = e1.getTime();
long ss2 = s2.getTime();
long ee2 = e2.getTime();
if((ss1<ss2) && (ee1>ss2)){
return 1;
}else if((ss1>ss2)&&(ss1<ee2)){
return 1;
}else{
return 0;
}
} catch (ParseException e) {
e.printStackTrace();
}
return 1;
}
/**
* 根据 年 和 月 得到下一个月的所有日子
* 配合 getCurrentYMD() 食用
*
* @param yearParam
* @param monthParam
* @return
*/
public static List<String> getNextDayByMonth(int yearParam, int monthParam) {
List list = new ArrayList();
Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
aCalendar.set(yearParam, monthParam, 1);
int year = aCalendar.get(Calendar.YEAR);//年份
int month = aCalendar.get(Calendar.MONTH) + 1;//月份
int day = aCalendar.getActualMaximum(Calendar.DATE);
for (int i = 1; i <= day; i++) {
String aDate = null;
if (month < 10 && i < 10) {
aDate = String.valueOf(year) + "-0" + month + "-0" + i;
}
if (month < 10 && i >= 10) {
aDate = String.valueOf(year) + "-0" + month + "-" + i;
}
if (month >= 10 && i < 10) {
aDate = String.valueOf(year) + "-" + month + "-0" + i;
}
if (month >= 10 && i >= 10) {
aDate = String.valueOf(year) + "-" + month + "-" + i;
}
list.add(aDate);
}
return list;
}
/**
* 根据日期(字符串)得到这一天的星期几
*
* @param pTime
* @return
* @throws Throwable
*/
public static Integer dayForWeek(String pTime) throws Throwable {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date tmpDate = format.parse(pTime);
Calendar cal = Calendar.getInstance();
Integer[] weekDays = {7, 1, 2, 3, 4, 5, 6};
try {
cal.setTime(tmpDate);
} catch (Exception e) {
e.printStackTrace();
}
int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
if (w < 0) {
w = 0;
}
return weekDays[w];
}
/**
* 根据开始日期、结束日期,获取中间日期(包括开始日期、结束日期)的字符串
*/
public static List<String> findDates(String startDay, String endStart)
throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
Date dBegin = sdf.parse(startDay);
Date dEnd = sdf.parse(endStart);
List<String> allDate = new ArrayList();
allDate.add(sdf1.format(dBegin));
Calendar calBegin = Calendar.getInstance();
// 使用给定的 Date 设置此 Calendar 的时间
calBegin.setTime(dBegin);
Calendar calEnd = Calendar.getInstance();
// 使用给定的 Date 设置此 Calendar 的时间
calEnd.setTime(dEnd);
// 测试此日期是否在指定日期之后
while (dEnd.after(calBegin.getTime())) {
// 根据日历的规则,为给定的日历字段添加或减去指定的时间量
calBegin.add(Calendar.DAY_OF_MONTH, 1);
allDate.add(sdf1.format(calBegin.getTime()));
}
return allDate;
}
/**
* 根据年月获取当月最后一天 (yyyyMMdd)
* @param yearAndMonth
* @return
*/
public static Date getlastDayOfMonth (String yearAndMonth){
String year = yearAndMonth.substring(0, 4);
String month = yearAndMonth.substring(4, 6);
String monthStr = (Integer.parseInt(month)-1)+"";
Calendar calendar = Calendar.getInstance();
// 设置时间,当前时间不用设置
calendar.set(Calendar.YEAR, Integer.parseInt(year));
calendar.set(Calendar.MONTH, Integer.parseInt(monthStr));
System.out.println(calendar.getTime());
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
Date time = calendar.getTime();
return time;
}
/**
* 根据年月获取当月第一天 (yyyyMMdd)
* @param yearAndMonth
* @return
*/
public static Date getFristDayOfMonth(String yearAndMonth){
String year = yearAndMonth.substring(0, 4);
String month = yearAndMonth.substring(4, 6);
String monthStr = (Integer.parseInt(month)-1)+"";
Calendar calendar = Calendar.getInstance();
// 设置时间,当前时间不用设置
calendar.set(Calendar.YEAR, Integer.parseInt(year));
calendar.set(Calendar.MONTH, Integer.parseInt(monthStr));
System.out.println(calendar.getTime());
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DATE));
Date time = calendar.getTime();
return time;
}
}
通用活动时间段计算方法:
public static List<String> commonTimeStageAlgorithm(String activStartTime
, String activEndTime
, String restStartTime
, String restEndTime
, Integer cutStageVal) throws ParseException {
//活动起始时间不允许为空
if (!StringUtils.isNotBlank(activStartTime) || !StringUtils.isNotBlank(activEndTime)) {
return null;
}
//处理,休息时间为null时
if (!StringUtils.isNotBlank(restStartTime) || !StringUtils.isNotBlank(restEndTime)) {
// haircutEntity.setRestStartTime("2020-01-01 12:00:00"); //给个形式时间,其实就是归零
// haircutEntity.setRestEndTime("2020-01-01 12:00:00");
//可能整个活动时间只有上午,故改
restStartTime = restEndTime;
restEndTime = activEndTime;
}
//得到 HH:mm格式的开始结束时间,方便等会代入我写好的封装方法
String activStartTime1 = DateStrUtils.getHM(activStartTime);
String activEndTime1 = DateStrUtils.getHM(activEndTime);
String restStartTime1 = DateStrUtils.getHM(restStartTime);
String restEndTime1 = DateStrUtils.getHM(restEndTime);
// 分为上、下两个半场来算
List<String> timeStageList = new ArrayList<String>();
String timeStageStart = activStartTime1;
while (true) {
String timeStageEnd = DateStrUtils.addOrSubMinutesTime(timeStageStart, cutStageVal, DateStrUtils.PATTERN_Hm);
//当结束时间段不小于休息时间起始时,结束
if (!DateStrUtils.compareIsBefore(timeStageEnd, restStartTime1, DateStrUtils.PATTERN_Hm)) {
timeStageList.add(timeStageStart + "-" + restStartTime1);
break;
}
timeStageList.add(timeStageStart + "-" + timeStageEnd);
timeStageStart = timeStageEnd;
}
//如果休息时间起止相等,则不用再计算下半场了。不相等时再计算
if(!restStartTime.equals(restEndTime)){
//存在下半场
String halfTimeStageStart = restEndTime1;
while (true) {
String halftimeStageEnd = DateStrUtils.addOrSubMinutesTime(halfTimeStageStart, cutStageVal, DateStrUtils.PATTERN_Hm);
//当结束时间段不小于活动结束时间,结束
if (!DateStrUtils.compareIsBefore(halftimeStageEnd, activEndTime1, DateStrUtils.PATTERN_Hm)) {
timeStageList.add(halfTimeStageStart + "-" + activEndTime1);
break;
}
timeStageList.add(halfTimeStageStart + "-" + halftimeStageEnd);
halfTimeStageStart = halftimeStageEnd;
}
}
return timeStageList;
}
结果:
通用,计算起始日期(字符串类型)获取中间日期(包括开始日期、结束日期)(字符串类型)
https://www.cnblogs.com/hyhy904/p/10930686.html
冷知识:mysql也可以对时间进行加减DATE_ADD(a.activ_end_time, INTERVAL 6 HOUR)
mysql可以直接拿“字符串类型的时间”和“时间”比较,真贴心舒心好用,就是不知道不是时间格式的字符串,去比较,会不会抛异常_。总结:mysql是不是对数据类型不敏感啊,真棒 (mysql看做弱类型语言/对数据类型不敏感?😀))
另外,mysql中判断!=null 或空字符串,使用: ISNULL(aBegBalRule) || LENGTH(trim(aBegBalRule))<1
或者 header_pic is not null and header_pic=''