JAVA获取N个工作日后的时间的工具类、考虑上班时间、时区

 DayWorkTime代表工作时间描述类

 HolidayUtils是计算时间的工具类,addSecondByWorkDay用于计算时间加上指定秒后的工作时间,会自动跳过周末、节假日等。其中holidayList参数是一个yyyy-MM-dd格式的日期字符串集合。

main方法放开则为一些基本测试案例。

package com.czq.util;

import lombok.Data;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

import static java.time.temporal.ChronoUnit.SECONDS;

/**
 * @author Administrator
 * @date   2021/2/5 0005 16:25
 */
@Data
public class DayWorkTime
{
	
	/**
	 * 日工作时长(秒)
	 */
	private long dayWorkSecond;
	
	/**
	 * 日开始工作时间到日结束工作时间之间的休息时间
	 */
	private long restTime;
	
	/**
	 * 日开始工作时间
	 */
	private LocalTime startTime;
	
	/**
	 * 日结束工作时间
	 */
	private LocalTime endTime;
	
	/**
	 * 日工作时间段(timeIntervals是按照时间顺序排序)
	 */
	private List<TimeInterval> timeIntervals;
	
	/**
	 * 工作时间的时区
	 */
	private TimeZone timeZone;
	
	@Getter
	public static class TimeInterval
	{
		private long workSecond;
		
		private LocalTime start;
		
		private LocalTime end;
		
		public TimeInterval(LocalTime start, LocalTime end)
		{
			if(start.compareTo(end) >= 0)
				throw new IllegalArgumentException("start is greater than end");
			
			this.start = start;
			this.end = end;
			this.workSecond = SECONDS.between(start, end);
		}
		
		public boolean inTimeInterval(LocalTime date)
		{
			return date.compareTo(start) >= 0 && date.compareTo(end) <= 0;
		}
	}
	
	/**
	 * 判断是否在工作时间段内
	 * 
	 * @param  date
	 * @return
	 */
	public boolean inTimeInterval(LocalTime date)
	{
		for(TimeInterval timeInterval : timeIntervals)
		{
			if(timeInterval.inTimeInterval(date))
				return true;
		}
		return false;
	}
	
	/**
	 * 计算日开始工作时间到date之间的秒钟数
	 * 
	 * @param  date
	 * @return
	 */
	public long betweenStartTime(LocalTime date)
	{
		long workMinutes = 0;
		// 如果date比上班时间还小,则返回0
		if(date.compareTo(startTime) < 0)
		{
			return workMinutes;
		}
		for(TimeInterval timeInterval : timeIntervals)
		{
			if(timeInterval.inTimeInterval(date))
			{
				workMinutes = workMinutes + SECONDS.between(timeInterval.start, date);
				break;
			}
			else
			{
				workMinutes = workMinutes + timeInterval.getWorkSecond();
			}
		}
		return workMinutes;
	}
	
	/**
	 * 计算date到日结束工作时间之间的秒钟数
	 * 
	 * @param  date
	 * @return
	 */
	public long betweenEndTime(LocalTime date)
	{
		long workMinutes = 0;
		// 如果date比下班时间还大,则返回0
		if(date.compareTo(endTime) > 0)
		{
			return workMinutes;
		}
		
		int i = timeIntervals.size() - 1;
		while(i >= 0)
		{
			TimeInterval timeInterval = timeIntervals.get(i);
			if(timeInterval.inTimeInterval(date))
			{
				workMinutes = workMinutes + SECONDS.between(date, timeInterval.end);
				break;
			}
			else
			{
				workMinutes = workMinutes + timeInterval.getWorkSecond();
			}
			i--;
		}
		return workMinutes;
	}
	
	/**
	 * 解析工作时间段配置如:09:00|12:00,13:00|18:00。时间需按从小到大顺序配置
	 * 
	 * @param  sWorkTime
	 * @return
	 */
	public static DayWorkTime parseWorkTime(String sWorkTime, String timeZoneId)
	{
		List<TimeInterval> timeIntervals = new ArrayList<>();
		
		LocalTime lastEndTime = null;
		LocalTime dayStartTime = null;
		long workOneDaySecond = 0;
		long restTime = 0;
		int index = 0;
		String[] split = StringUtils.split(sWorkTime, ",");
		for(String s : split)
		{
			String[] time = StringUtils.split(s, "|");
			LocalTime startTime = LocalTime.parse(time[0]);
			if(index == 0)
			{
				dayStartTime = startTime;
			}
			LocalTime endTime = LocalTime.parse(time[1]);
			workOneDaySecond = workOneDaySecond + SECONDS.between(startTime, endTime);
			
			TimeInterval timeInterval = new TimeInterval(startTime, endTime);
			timeIntervals.add(timeInterval);
			
			// 	计算中间休息时间
			if(lastEndTime == null)
			{
				lastEndTime = endTime;
			}
			else
			{
				restTime = restTime + SECONDS.between(lastEndTime, startTime);
				lastEndTime = endTime;
			}
			index++;
		}
		
		if(workOneDaySecond == 0)
			throw new RuntimeException("workOneDayMinutes exception");
		
		DayWorkTime workTime = new DayWorkTime();
		workTime.setTimeIntervals(timeIntervals);
		workTime.setDayWorkSecond(workOneDaySecond);
		workTime.setRestTime(restTime);
		workTime.setStartTime(dayStartTime);
		workTime.setEndTime(lastEndTime);
		
		workTime.setTimeZone(TimeZone.getTimeZone(timeZoneId));
		return workTime;
	}
	
}
package com.czq.util;

import com.czq.util.DayWorkTime;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

import static java.time.temporal.ChronoUnit.SECONDS;

/**
 * @author Administrator
 * @date   2021/2/6 0006 21:37
 */
public class HolidayUtils
{
	
	private static Logger logger = LoggerFactory.getLogger(HolidayUtils.class);
	
	/**
	 * 根据date的日期和time的时间组装
	 *
	 * @param  date
	 * @param  time
	 * @return
	 */
	private static Date assemblyTime(Date date, LocalTime time, TimeZone timeZone)
	{
		Calendar calendar = Calendar.getInstance(timeZone);
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, time.getHour());
		calendar.set(Calendar.MINUTE, time.getMinute());
		calendar.set(Calendar.SECOND, time.getSecond());
		calendar.set(Calendar.MILLISECOND, time.getNano() / 1000000);
		
		return calendar.getTime();
	}
	
	/**
	 * date根据时区转换成LocalTime
	 *
	 * @param  date
	 * @param  timeZone
	 * @return
	 */
	private static LocalTime dateToLocalTime(Date date, TimeZone timeZone)
	{
		LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), timeZone.toZoneId());
		return localDateTime.toLocalTime();
	}
	
	/**
	 * 判断是否为同一天
	 * 
	 * @param  d1
	 * @param  d2
	 * @param  timeZone
	 * @return
	 */
	private static boolean isSameDay(Date d1, Date d2, TimeZone timeZone)
	{
		Calendar cal1 = Calendar.getInstance(timeZone);
		cal1.setTime(d1);
		
		Calendar cal2 = Calendar.getInstance(timeZone);
		cal2.setTime(d2);
		
		return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
	}
	
	/**
	 * 根据自然日获取指定时间
	 * 
	 * @param  date
	 * @param  totalSecond
	 * @return
	 */
	public static Date getScheduleByNaturalDay(Date date, int totalSecond)
	{
		return addSecond(date, totalSecond);
	}
	
	/**
	 * 根据自然日计算startDate到endDate之间的工作时间(秒数)
	 * 
	 * @param  startDate
	 * @param  endDate
	 * @return
	 */
	public static long betweenTimeByNaturalDay(Date startDate, Date endDate)
	{
		long diff = endDate.getTime() - startDate.getTime();
		return diff / 1000;
	}
	
	/**
	 * 根据工作日和工作时间计算startDate到endDate之间的工作时间(秒数)
	 * 
	 * @param  dayWorkTime
	 * @param  holidayList
	 * @param  startDate
	 * @param  endDate
	 * @return
	 */
	public static long betweenTimeByWorkingDay(DayWorkTime dayWorkTime, Set<String> holidayList, Date startDate, Date endDate)
	{
		TimeZone timeZone = dayWorkTime.getTimeZone();
		if(noWorkDay(startDate, holidayList, timeZone))
		{//如果是假期或周末,则开始时间为下一个工作日的上班时间
			startDate = getTomorrowByWorkDay(startDate, holidayList, 1, timeZone);
			startDate = assemblyTime(startDate, dayWorkTime.getStartTime(), timeZone);
			if(startDate.after(endDate))
			{
				return 0;
			}
		}
		
		LocalTime startTime = dateToLocalTime(startDate, timeZone);
		LocalTime endTime = dateToLocalTime(endDate, timeZone);
		// 判断是否为同一天
		if(isSameDay(startDate, endDate, timeZone))
		{
			if(startTime.compareTo(dayWorkTime.getStartTime()) <= 0)
			{
				if(endTime.compareTo(dayWorkTime.getEndTime()) >= 0)
					return dayWorkTime.getDayWorkSecond();
				else
					return dayWorkTime.betweenStartTime(endTime);
			}
			else
			{
				if(startTime.compareTo(dayWorkTime.getEndTime()) <= 0)
				{
					if(endTime.compareTo(dayWorkTime.getEndTime()) >= 0)
						return dayWorkTime.betweenEndTime(startTime);
					else
						return dayWorkTime.getDayWorkSecond() - dayWorkTime.betweenStartTime(startTime)
							- dayWorkTime.betweenEndTime(endTime);
				}
				else
				{
					return 0;
				}
			}
		}
		else
		{// 如果不是同一天,则一天天的时间相加,先计算当天时间,再计算下一天的时间
			long time = 0;
			if(startTime.compareTo(dayWorkTime.getStartTime()) <= 0)
			{
				time = time + dayWorkTime.getDayWorkSecond();
			}
			else
			{
				if(startTime.compareTo(dayWorkTime.getEndTime()) <= 0)
				{
					time = time + dayWorkTime.betweenEndTime(startTime);
				}
				else
				{
					// time = time + 0;
				}
			}
			
			Date tomorrow = getTomorrow(startDate, dayWorkTime.getTimeZone());
			while(!isSameDay(tomorrow, endDate, timeZone))
			{
				if(isWeekend(tomorrow, dayWorkTime.getTimeZone()) || isHoliday(tomorrow, holidayList, dayWorkTime.getTimeZone()))
				{
					// time = time + 0;
				}
				else
				{
					time = time + dayWorkTime.getDayWorkSecond();
				}
				tomorrow = getTomorrow(tomorrow, dayWorkTime.getTimeZone());
			}
			
			if(endTime.compareTo(dayWorkTime.getStartTime()) <= 0)
			{
				// time = time + 0;
			}
			else
			{
				if(endTime.compareTo(dayWorkTime.getEndTime()) >= 0)
					time = time + dayWorkTime.getDayWorkSecond();
				else
					time = time + dayWorkTime.betweenStartTime(endTime);
			}
			return time;
		}
	}
	
	/**
	 * 获取tomorrow的日期
	 *
	 * @param  date
	 * @return
	 */
	public static Date getTomorrow(Date date, TimeZone timeZone)
	{
		Calendar calendar = Calendar.getInstance(timeZone);
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, +1);
		date = calendar.getTime();
		return date;
	}
	
	/**
	 * 根据当前日期获取下n个工作日
	 * 
	 * @param  today
	 * @param  holidayList
	 * @param  days
	 *                         n个日期后
	 * @param  timeZone
	 * @return
	 */
	public static Date getTomorrowByWorkDay(Date today, Set<String> holidayList, int days, TimeZone timeZone)
	{
		Date tomorrow;
		int delay = 1;
		while(delay <= days)
		{
			tomorrow = getTomorrow(today, timeZone);
			//当前日期+1,判断是否是节假日,不是的同时要判断是否是周末,都不是则scheduleActiveDate日期+1
			if(isHoliday(tomorrow, holidayList, timeZone))
			{
				today = tomorrow;
			}
			else if(isWeekend(tomorrow, timeZone))
			{
				today = tomorrow;
			}
			else
			{
				delay++;
				today = tomorrow;
			}
		}
		return today;
	}
	
	/**
	 * 获取Yesterday的日期
	 *
	 * @param  date
	 * @return
	 */
	public static Date getYesterday(Date date, TimeZone timeZone)
	{
		Calendar calendar = Calendar.getInstance(timeZone);
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		date = calendar.getTime();
		return date;
	}
	
	/**
	 * 根据当前日期获取上n个工作日
	 * 
	 * @param  today
	 * @param  holidayList
	 * @param  days
	 * @param  timeZone
	 * @return
	 */
	public static Date getYesterdayByWorkDay(Date today, Set<String> holidayList, int days, TimeZone timeZone)
	{
		Date yesterday;
		int delay = 1;
		while(delay <= days)
		{
			yesterday = getYesterday(today, timeZone);
			//当前日期+1,判断是否是节假日,不是的同时要判断是否是周末,都不是则scheduleActiveDate日期+1
			if(isHoliday(yesterday, holidayList, timeZone))
			{
				today = yesterday;
			}
			else if(isWeekend(yesterday, timeZone))
			{
				today = yesterday;
			}
			else
			{
				delay++;
				today = yesterday;
			}
		}
		return today;
	}
	
	/**
	 * 添加秒钟数
	 *
	 * @param  date
	 * @param  second
	 * @return
	 */
	public static Date addSecond(Date date, int second)
	{
		long time = second * 1000;
		date = new Date(date.getTime() + time);
		return date;
	}
	
	/**
	 * 判断是否是weekend
	 *
	 * @param  date
	 * @return
	 */
	public static boolean isWeekend(Date date, TimeZone timeZone)
	{
		Calendar cal = Calendar.getInstance(timeZone);
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY;
	}
	
	/**
	 * 判断是否是holiday
	 *
	 * @param  date
	 * @param  holidayList
	 * @return
	 */
	public static boolean isHoliday(Date date, Set<String> holidayList, TimeZone timeZone)
	{
		if(holidayList != null && holidayList.size() > 0)
		{
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			sdf.setTimeZone(timeZone);
			String sdate = sdf.format(date);
			return holidayList.contains(sdate);
		}
		return false;
	}
	
	/**
	 * 非工作日
	 * 
	 * @param  date
	 * @param  holidayList
	 * @param  timeZone
	 * @return
	 */
	public static boolean noWorkDay(Date date, Set<String> holidayList, TimeZone timeZone)
	{
		return isWeekend(date, timeZone) || isHoliday(date, holidayList, timeZone);
	}
	
	/**
	 * 减掉指定秒后的时间
	 * 
	 * @param  dayWorkTime
	 * @param  date
	 * @param  holidayList
	 * @param  second
	 * @return
	 */
	public static Date subSecondByWorkDay(DayWorkTime dayWorkTime, Date date, Set<String> holidayList, long second)
	{
		long dayWorkSecond = dayWorkTime.getDayWorkSecond();
		int day = (int) (second / dayWorkSecond);
		long remainingSecond = second % dayWorkSecond;
		
		TimeZone timeZone = dayWorkTime.getTimeZone();
		LocalTime localTime = dateToLocalTime(date, timeZone);
		if(isHoliday(date, holidayList, timeZone) || isWeekend(date, timeZone))
		{
			//如果是假期或周末,则开始时间为上一个工作日的下班时间
			date = getYesterdayByWorkDay(date, holidayList, 1, timeZone);
			localTime = dayWorkTime.getEndTime();
		}
		
		boolean greaterThanStartTime = localTime.compareTo(dayWorkTime.getStartTime()) >= 0;
		boolean lessThanEndTime = localTime.compareTo(dayWorkTime.getEndTime()) <= 0;
		
		if(!greaterThanStartTime || !lessThanEndTime)
		{// 小于开始工作时间或大于结束工作时间
			if(!greaterThanStartTime)
			{ // 小于开始工作时间,则多加一天
				day = day + 1;
			}
			localTime = dayWorkTime.getEndTime();
			date = assemblyTime(date, localTime, timeZone);
			date = getYesterdayByWorkDay(date, holidayList, day, timeZone);
			
			List<DayWorkTime.TimeInterval> timeIntervals = dayWorkTime.getTimeIntervals();
			for(int i = timeIntervals.size() - 1; i >= 0; i--)
			{
				DayWorkTime.TimeInterval timeInterval = timeIntervals.get(i);
				long workSecond = timeInterval.getWorkSecond();
				if(workSecond > remainingSecond)
				{
					localTime = localTime.minusSeconds(remainingSecond);
					break;
				}
				else
				{
					remainingSecond = remainingSecond - workSecond;
					localTime = timeInterval.getStart();
				}
			}
			
			date = assemblyTime(date, localTime, timeZone);
			return date;
		}
		else
		{// 在上班时间内
			List<DayWorkTime.TimeInterval> timeIntervals = dayWorkTime.getTimeIntervals();
			
			// 确认是否在上班时间段内,不在上班时间段内,则校准在上班时间段内
			for(int i = timeIntervals.size() - 1; i >= 0; i--)
			{
				DayWorkTime.TimeInterval timeInterval = timeIntervals.get(i);
				if(timeInterval.inTimeInterval(localTime))
				{
					break;
				}
				else
				{
					int index = i - 1;
					if(index >= 0)
					{
						DayWorkTime.TimeInterval nextTimeInterval = timeIntervals.get(index);
						if(localTime.compareTo(nextTimeInterval.getEnd()) >= 0 && localTime.compareTo(timeInterval.getStart()) <= 0)
						{
							localTime = nextTimeInterval.getEnd();
							break;
						}
					}
				}
			}
			date = assemblyTime(date, localTime, timeZone);
			date = getYesterdayByWorkDay(date, holidayList, day, timeZone);
			
			// 减去秒数
			out:
			for(int i = timeIntervals.size() - 1; i >= 0; i--)
			{
				DayWorkTime.TimeInterval timeInterval = timeIntervals.get(i);
				if(timeInterval.inTimeInterval(localTime))
				{
					long timeIntervalRemainingSecond = SECONDS.between(timeInterval.getStart(), localTime);
					if(timeIntervalRemainingSecond >= remainingSecond)
					{
						localTime = localTime.minusSeconds(remainingSecond);
						break;
					}
					else
					{
						remainingSecond = remainingSecond - timeIntervalRemainingSecond;
						
						int index = i - 1;
						while(index >= 0)
						{
							DayWorkTime.TimeInterval nextTimeInterval = timeIntervals.get(index);
							long workSecond = nextTimeInterval.getWorkSecond();
							if(workSecond > remainingSecond)
							{
								localTime = nextTimeInterval.getEnd();
								localTime = localTime.minusSeconds(remainingSecond);
								break out;
							}
							else
							{
								remainingSecond = remainingSecond - workSecond;
							}
							index--;
						}
					}
				}
			}
			date = assemblyTime(date, localTime, timeZone);
			return date;
		}
	}
	
	/**
	 * 加上指定秒后的时间
	 *
	 * @param  dayWorkTime
	 * @param  date
	 * @param  holidayList
	 * @param  second
	 * @return
	 */
	public static Date addSecondByWorkDay(DayWorkTime dayWorkTime, Date date, Set<String> holidayList, long second)
	{
		long dayWorkSecond = dayWorkTime.getDayWorkSecond();
		int day = (int) (second / dayWorkSecond);
		long remainingSecond = second % dayWorkSecond;
		
		TimeZone timeZone = dayWorkTime.getTimeZone();
		LocalTime localTime = dateToLocalTime(date, timeZone);
		
		if(isHoliday(date, holidayList, timeZone) || isWeekend(date, timeZone))
		{
			//如果是假期或周末,则开始时间为下一个工作日的上班时间
			date = getTomorrowByWorkDay(date, holidayList, 1, timeZone);
			localTime = dayWorkTime.getStartTime();
		}
		
		boolean greaterThanStartTime = localTime.compareTo(dayWorkTime.getStartTime()) >= 0;
		boolean lessThanEndTime = localTime.compareTo(dayWorkTime.getEndTime()) <= 0;
		if(greaterThanStartTime && lessThanEndTime)//在开始工作时间和结束时间内
		{
			List<DayWorkTime.TimeInterval> timeIntervals = dayWorkTime.getTimeIntervals();
			for(int i = 0, l = timeIntervals.size(); i < l; i++)// 确认是否在上班时间段内,不在上班时间段内,则校准在上班时间段内
			{
				DayWorkTime.TimeInterval timeInterval = timeIntervals.get(i);
				if(timeInterval.inTimeInterval(localTime))
				{
					break;
				}
				{
					int index = i + 1;
					if(index < l)
					{
						DayWorkTime.TimeInterval nextTimeInterval = timeIntervals.get(index);
						if(localTime.compareTo(timeInterval.getEnd()) >= 0 && localTime.compareTo(nextTimeInterval.getStart()) <= 0)
						{
							localTime = nextTimeInterval.getStart();
							break;
						}
					}
				}
			}
			
			date = assemblyTime(date, localTime, timeZone);
			date = getTomorrowByWorkDay(date, holidayList, day, timeZone);
			
			// 加秒数
			out:
			for(int i = 0, l = timeIntervals.size(); i < l; i++)
			{
				DayWorkTime.TimeInterval timeInterval = timeIntervals.get(i);
				if(timeInterval.inTimeInterval(localTime))
				{
					long timeIntervalRemainingSecond = SECONDS.between(localTime, timeInterval.getEnd());
					if(timeIntervalRemainingSecond >= remainingSecond)
					{
						localTime = localTime.plusSeconds(remainingSecond);
						break;
					}
					else
					{
						remainingSecond = remainingSecond - timeIntervalRemainingSecond;
						
						int index = i + 1;
						while(index < l)
						{
							DayWorkTime.TimeInterval nextTimeInterval = timeIntervals.get(index);
							long workSecond = nextTimeInterval.getWorkSecond();
							if(workSecond > remainingSecond)
							{
								localTime = nextTimeInterval.getStart();
								localTime = localTime.plusSeconds(remainingSecond);
								break out;
							}
							else
							{
								remainingSecond = remainingSecond - workSecond;
							}
							index++;
						}
					}
				}
			}
			date = assemblyTime(date, localTime, timeZone);
		}
		else
		{
			if(!lessThanEndTime)// 大于结束工作时间,则多加一天
			{
				day = day + 1;
			}
			localTime = dayWorkTime.getStartTime();
			date = assemblyTime(date, localTime, timeZone);
			date = getTomorrowByWorkDay(date, holidayList, day, timeZone);
			
			List<DayWorkTime.TimeInterval> timeIntervals = dayWorkTime.getTimeIntervals();
			for(int i = 0, l = timeIntervals.size(); i < l; i++)
			{
				DayWorkTime.TimeInterval timeInterval = timeIntervals.get(i);
				long workSecond = timeInterval.getWorkSecond();
				if(workSecond > remainingSecond)
				{
					localTime = localTime.plusSeconds(remainingSecond);
					break;
				}
				else
				{
					remainingSecond = remainingSecond - workSecond;
					localTime = timeInterval.getStart();
				}
			}
			date = assemblyTime(date, localTime, timeZone);
		}
		
		// 如果开始时间上班时间点,则置为上一个工作日的下班时间
		LocalTime startTime = dateToLocalTime(date, timeZone);
		if(compareLocalTime(startTime, dayWorkTime.getStartTime()))
		{
			date = getYesterdayByWorkDay(date, holidayList, 1, timeZone);
			date = assemblyTime(date, dayWorkTime.getEndTime(), timeZone);
		}
		return date;
	}
	
	public static boolean compareLocalTime(LocalTime t1, LocalTime t2)
	{
		if(t1.getHour() == t2.getHour() && t1.getMinute() == t2.getMinute() && t1.getSecond() == t2.getSecond())
			return true;
		return false;
	}
	
	public static String slaTargetToString(long second)
	{
		String result = "";
		long h = second / 3600;
		if(h > 0)
		{
			result = h + "Hours ";
		}
		
		long m = (second % 3600) / 60;
		if(m > 0)
		{
			result = result + m + "Minutes";
		}
		
		if(StringUtils.isEmpty(result))
		{
			result = "0m";
		}
		return result;
	}
	
//	public static void main(String[] args) throws ParseException
//	{
//		Case1();
//	}
	
	private static void Case1() throws ParseException
	{
		// 上海时区
		DayWorkTime dayWorkTime = DayWorkTime.parseWorkTime("07:00|17:00", "Asia/Shanghai");
		SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		TimeZone timeZone2 = TimeZone.getTimeZone("Asia/Shanghai");
		simpleDateFormat2.setTimeZone(timeZone2);
		
		// 案例1,周末40小时 2021-10-31 09:44:00=》2021-11-04 17:00:00
		Date createDate1 = simpleDateFormat2.parse("2021-10-31 09:44:00");
		System.out.println(simpleDateFormat2.format(createDate1));
		Date date1 = addSecondByWorkDay(dayWorkTime, createDate1, new HashSet<String>(), 40 * 60 * 60);
		System.out.println(simpleDateFormat2.format(date1));
		System.out.println("案例1,周末40小时。结果:" + ("2021-11-04 17:00:00".equals(simpleDateFormat2.format(date1))));
		date1 = subSecondByWorkDay(dayWorkTime, date1, new HashSet<String>(), 40 * 60 * 60);
		System.out.println("sub: " + simpleDateFormat2.format(date1));
		System.out.println();
		
		// 案例2,工作日、上班时间段前,5小时 2021-11-01 05:44:00=》2021-11-01 12:00:00
		Date createDate2 = simpleDateFormat2.parse("2021-11-01 05:44:00");
		System.out.println(simpleDateFormat2.format(createDate2));
		Date date2 = addSecondByWorkDay(dayWorkTime, createDate2, new HashSet<String>(), 5 * 60 * 60);
		System.out.println(simpleDateFormat2.format(date2));
		System.out.println("案例2,工作日、上班时间段前,5小时。结果:" + ("2021-11-01 12:00:00".equals(simpleDateFormat2.format(date2))));
		date2 = subSecondByWorkDay(dayWorkTime, date2, new HashSet<String>(), 5 * 60 * 60);
		System.out.println("sub: " + simpleDateFormat2.format(date2));
		System.out.println();
		
		// 案例3,工作日、上班时间段内、5小时 2021-11-01 08:44:00=》2021-11-01 13:44:00
		Date createDate3 = simpleDateFormat2.parse("2021-11-01 08:44:00");
		System.out.println(simpleDateFormat2.format(createDate3));
		Date date3 = addSecondByWorkDay(dayWorkTime, createDate3, new HashSet<String>(), 5 * 60 * 60);
		System.out.println(simpleDateFormat2.format(date3));
		System.out.println("案例3,工作日、上班时间段内、5小时。结果:" + ("2021-11-01 13:44:00".equals(simpleDateFormat2.format(date3))));
		date3 = subSecondByWorkDay(dayWorkTime, date3, new HashSet<String>(), 5 * 60 * 60);
		System.out.println("sub: " + simpleDateFormat2.format(date3));
		System.out.println();
		
		// 案例4,工作日、上班时间段后、5小时 2021-11-01 21:44:00=》2021-11-01 14:44:00
		Date createDate4 = simpleDateFormat2.parse("2021-11-01 21:44:00");
		System.out.println(simpleDateFormat2.format(createDate4));
		Date date4 = addSecondByWorkDay(dayWorkTime, createDate4, new HashSet<String>(), 5 * 60 * 60);
		System.out.println(simpleDateFormat2.format(date4));
		System.out.println("案例4,工作日、上班后、5小时。结果:" + ("2021-11-02 12:00:00".equals(simpleDateFormat2.format(date4))));
		date4 = subSecondByWorkDay(dayWorkTime, date4, new HashSet<String>(), 5 * 60 * 60);
		System.out.println("sub: " + simpleDateFormat2.format(date4));
		System.out.println();
		
		// 案例5,工作日、上班时间段内、50小时、15分钟 2021-09-22 11:16:03=》2021-09-24 11:16:03
		Date createDate5 = simpleDateFormat2.parse("2021-11-02 11:16:03");
		System.out.println(simpleDateFormat2.format(createDate5));
		Date date5 = addSecondByWorkDay(dayWorkTime, createDate5, new HashSet<String>(), 50 * 60 * 60 + 15 * 60);
		System.out.println(simpleDateFormat2.format(date5));
		System.out.println("案例5,随机。结果:" + ("2021-11-09 11:31:03".equals(simpleDateFormat2.format(date5))));
		date5 = subSecondByWorkDay(dayWorkTime, date5, new HashSet<String>(), 50 * 60 * 60 + 15 * 60);
		System.out.println("sub: " + simpleDateFormat2.format(date5));
		System.out.println();
		
		// 案例5,工作日、5小时、15分钟、正好到下班时间截止 2021-09-22 11:45:00=》2021-09-24 17:00:00
		Date createDate6 = simpleDateFormat2.parse("2021-09-22 11:45:00");
		System.out.println(simpleDateFormat2.format(createDate6));
		Date date6 = addSecondByWorkDay(dayWorkTime, createDate6, new HashSet<String>(), 5 * 60 * 60 + 15 * 60);
		System.out.println(simpleDateFormat2.format(date6));
		System.out.println("案例5,工作日、5小时、15分钟、正好到下班时间截止。结果:" + ("2021-09-22 17:00:00".equals(simpleDateFormat2.format(date6))));
		date6 = subSecondByWorkDay(dayWorkTime, date6, new HashSet<String>(), 5 * 60 * 60 + 15 * 60);
		System.out.println("sub: " + simpleDateFormat2.format(date6));
		System.out.println();

		// 案例6,差一秒问题
		SimpleDateFormat simpleDateFormat3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		Date createDate7 = simpleDateFormat3.parse("2021-11-17 03:58:09.691");
		System.out.println(simpleDateFormat3.format(createDate7));
		Date date7 = addSecondByWorkDay(dayWorkTime, createDate7, new HashSet<String>(), 100 * 60 * 60);
		System.out.println(simpleDateFormat3.format(date7));
	}
	
	private static void Case2() throws ParseException
	{
		
		DayWorkTime dayWorkTime = DayWorkTime.parseWorkTime("07:00|17:00", "Europe/Copenhagen");
		
		SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		TimeZone timeZone1 = TimeZone.getTimeZone("Europe/Copenhagen");
		simpleDateFormat1.setTimeZone(timeZone1);
		SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		TimeZone timeZone2 = TimeZone.getTimeZone("Asia/Shanghai");
		simpleDateFormat2.setTimeZone(timeZone2);
		// 案例7,随机 2021-11-01 09:00:08=》2021-11-16 14:00:01
		Date createDate7 = new Date(1635759140000L);
		System.out.println(simpleDateFormat1.format(createDate7));
		Date date7 = addSecondByWorkDay(dayWorkTime, createDate7, new HashSet<String>(), 360000);
		System.out.println(simpleDateFormat1.format(date7));
		System.out.println("案例7,随机。结果:" + ("2021-11-15 09:00:08".equals(simpleDateFormat1.format(date7))));
	}
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值