如何实现根据当前的日期,来确定前一个工作日

本文讨论了如何在包含节假日的情况下计算前一个工作日的日期,通过避免陷入循环判断,提出了一种新的算法解决方案。
业务场景一:
根据当前的日期判断前一个工作日是几号。
1),通常情况是:在周2到周6的这五天时间里,获取前一个工作日的方法是简单的,就是:proviousBusinessDate= CurrentDate -1;同理可以推导出:2) 周1是: proviousBusinessDate= CurrentDate - 3; 3)周日是:proviousBusinessDate= CurrentDate -2;
java代码的实现如下:

public static Date getPreviousBusinessDate(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);

int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);

if (dayOfWeek == Calendar.MONDAY) {
calendar.add(Calendar.DATE, -3);
} else if (dayOfWeek == Calendar.SUNDAY) {
calendar.add(Calendar.DATE, -2);
} else {
calendar.add(Calendar.DATE, -1);
}

return calendar.getTime();
}


业务场景二:
如果加入Holiday的情况,前一个工作日该如何确定。

现在情况有了变化,我们如果不仅仅要考虑周末休息天的情况,还要考虑holiday的节假日放假的场景的话,是否会有点不一样拟。
如果接着上面的思维:我们就会这样考虑:好了,我们不是根据当前的日期,拿到了前一个工作日了麽。那么我们就可以对这个日期再进行判断,如果previousBusinessDay是holiday的话,我们就再往前减一天,还是holiday就再减,一直到不是holiday为止(在这里holiday由一个holiday表来维护)。
代码就是:
if(holidayList.Contains(previousBusinessDay)){
previousBusinessDay = previousBusinessDay -1;
}

看到这个代码你是不是就看到bug了,这里有个问题是:当你减了很多天之后,你还是要再重新去判断你得到的这个日期是不是满足条件的,是不是在weekend里面,如果是在weekend里面的话,你得重新回去是周日周一及其他的情况。然后判断完了之后,你还得回来判断你是不是又回到了holiday.如此我们就陷入了一个死循环里面而无法自拔。

来吧,是时候跳出这个怪圈了。我们就不能换一种思路吗:
我们不管三七二十一先减一天,先拿到previousBusinessDay,然后再来判断我们拿到的这天是不是周末还是Holiday,如果是就减一,一直减直到减到不是为止。

show code:

/**
* get PreviousBusinessDate (exclude the holiday)
* @param date
* @param holidays
* @return
*/
public static Date getPreviousBusinessDate(Date date, List<Date> holidays) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DATE, -1);
Date prevDate = cal.getTime();
//if the prevDate is Holiday, then get the day before prevDate.
while(isHoliday(prevDate, holidays) || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY){
cal.add(Calendar.DATE, -1);
prevDate = cal.getTime();
}

return prevDate;
}


/**
* if the current Date is Holiday, return true, otherwise, return false
* @return
*/
public static boolean isHoliday(Date currentDate, List<Date> holidays) {
boolean isHoliday = false;
for (Date date : holidays) {
if(DateUtils.isSameDay(date, currentDate)) {
isHoliday = true;
break;
};
}
return isHoliday;
}



如果有谁路过此地,能给出更好的算法,请一定show出来

----EOF----
<think>好的,用户需要编写一个可以根据服务器上一年的日期,在工作日循环执行的脚本。首先,我需要明确用户的具体需求。用户提到“上一年的日期”,这可能是指脚本需要处理过去一年的日期,而“在工作日循环执行”可能意味着脚本需要在每个工作日运行,但可能是指过去一年的每个工作日?或者可能是用户希望脚本在每个工作日运行,但处理的是上一年的数据?这里需要进一步理解用户的需求。 首先,用户之的请求是关于显示当前时间并保存到日志文件的脚本,现在的问题则是关于循环执行,可能与定时任务有关。可能用户希望有一个脚本,能够遍历上一年的所有工作日,并在每个工作日执行某个任务。或者,用户希望脚本在每个工作日运行,但处理的是上一年的某个日期相关的任务?需要进一步分析。 接下来,用户提到“在工作日循环执行”,可能是指脚本需要自动在每个工作日运行,例如每周一至周五执行某个任务。而“根据服务器上一年的日期”可能是指脚本需要获取上一年的日期信息,并基于此进行循环。例如,可能需要生成过去一年的所有工作日日期,并对每个日期执行某个操作? 或者,用户可能希望编写一个定时任务(比如cron job),只在工作日运行,而该任务需要处理上一年的日期数据?这种情况下,脚本可能需要在每个工作日触发,然后处理上一年的对应日期数据? 需要明确用户的具体场景。可能的两种情况: 1. 脚本需要遍历上一年的所有工作日日期,并对每个日期执行某个任务。 2. 脚本需要在当前工作日(例如每周一至周五)定时执行,处理与上一年的日期相关的数据。 根据用户的提问,“编写一个可以根据服务器上一年的日期,在工作日循环执行的脚本”,可能更接近第一种情况:生成上一年的所有工作日日期,并循环处理这些日期。例如,统计过去一年的每个工作日的日志文件,或者进行数据备份等操作。 接下来,如何生成上一年的所有工作日日期?在shell脚本中,可以使用日期命令来计算日期,并循环遍历每一天,判断是否为工作日(周一至周五)。需要考虑闰年、月份天数等问题。或者,使用循环从上一年的第一天到最后一天,逐一检查每个日期是星期几,如果是周一到周五则视为工作日。 然后,脚本需要处理这些日期,可能执行某些命令或记录日志。例如,用户可能需要遍历每个工作日,并执行数据处理的脚本。 现在,编写这样的脚本需要注意以下几点: 1. 确定上一年的开始和结束日期。例如,如果当前是2023年10月,则上一年是2022年,从2022-01-01到2022-12-31。但需要注意,如果当前日期是1月,比如2024年1月5日,那么上一年是2023年,所以需要动态计算。 2. 循环遍历上一年的每一天,判断是否为工作日(周一到周五)。 3. 对每个工作日执行相应的操作,比如生成日志、处理文件等。 可能的实现步骤: 1. 计算上一年的开始和结束日期。例如,当前年份减去1年,得到上一年。注意处理跨年的情况,比如当前是2024年1月,那么上一年是2023年,所以开始是2023-01-01,结束是2023-12-31。 2. 使用循环,从开始日期到结束日期,逐日推进。 3. 对于每个日期,使用date命令判断是星期几。在shell中,date的%u格式符返回1-7(周一到周日),所以如果%u的值小于6,则是工作日。 4. 将符合条件的工作日日期存储起来,或者直接在该循环中执行需要的操作。 示例代码思路: ```bash #!/bin/bash # 获取当前年份的一年 last_year=$(date -d "1 year ago" "+%Y") # 设置上一年的开始和结束日期 start_date="${last_year}-01-01" end_date="${last_year}-12-31" # 循环遍历上一年的每一天 current_date="$start_date" while [ "$current_date" != "$end_date" ]; do # 检查当前日期是否为工作日(1-5为周一到周五) weekday=$(date -d "$current_date" "+%u") if [ "$weekday" -le 5 ]; then echo "处理工作日:$current_date" # 在这里执行需要的操作,例如调用其他脚本或命令 fi # 递增日期 current_date=$(date -d "$current_date + 1 day" "+%Y-%m-%d") done ``` 这个脚本会遍历上一年的每一天,判断是否为工作日,并输出处理信息。用户可以在if语句块中添加具体的操作。 但需要注意,date命令在不同的系统(如BSD和GNU)中的行为可能不同,例如macOS使用的是BSD的date,而Linux通常使用GNU date。例如,BSD的date命令可能需要使用-v-1y来调整年份,而GNU使用"-d '1 year ago'"。如果用户的环境是Linux,则上述脚本可行,但如果是macOS,则需要调整日期计算的语法。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值