Java 计算给定两个日期(不包括周末)的日期
我在Spring3.0项目中使用JodaTimeAPI来计算日期。现在我有了一个开始和结束日期,我想在这两个日期之间获得每天的例外周末或周六或周日。我怎样才能做到这一点 我看了这篇文章。Java 计算给定两个日期(不包括周末)的日期,java,datetime,jodatime,Java,Datetime,Jodatime,我在Spring3.0项目中使用JodaTimeAPI来计算日期。现在我有了一个开始和结束日期,我想在这两个日期之间获得每天的例外周末或周六或周日。我怎样才能做到这一点 我看了这篇文章。 它提供了一些指导,但对于如何排除两个日期仍然很模糊。您可以使用公历检索特定日期的日期。如果字符串是周六或周日,您可以忽略它 我想你的问题是如何 在两次约会之间,除周末、周六或周日外,每天都要休息 解决方案: public static void main(String[] args) { final L
它提供了一些指导,但对于如何排除两个日期仍然很模糊。您可以使用公历检索特定日期的日期。如果字符串是周六或周日,您可以忽略它 我想你的问题是如何 在两次约会之间,除周末、周六或周日外,每天都要休息 解决方案:
public static void main(String[] args) {
final LocalDate start = LocalDate.now();
final LocalDate end = new LocalDate(2012, 1, 14);
LocalDate weekday = start;
if (start.getDayOfWeek() == DateTimeConstants.SATURDAY ||
start.getDayOfWeek() == DateTimeConstants.SUNDAY) {
weekday = weekday.plusWeeks(1).withDayOfWeek(DateTimeConstants.MONDAY);
}
while (weekday.isBefore(end)) {
System.out.println(weekday);
if (weekday.getDayOfWeek() == DateTimeConstants.FRIDAY)
weekday = weekday.plusDays(3);
else
weekday = weekday.plusDays(1);
}
}
我是新来的。
我一直在寻找这个问题的解决方案,但没有使用循环,但没有找到合适的算法。所以我决定创建这个不使用循环的解决方案,非常高效,并且代码已经过测试
public int betweenDaysIgnoreWeekends(DateTime startDate, DateTime endDate) {
//Um numero que representa o dia da semana para a data final, exemplo segunda=1, terça=2, quarta=3...
int dayOfWeekEndDateNumber = Integer.valueOf(endDate.dayOfWeek()
.getAsString());
//Um numero que representa o dia da semana para a data inicial, exemplo segunda=1, terça=2, quarta=3...
int dayOfWeekStartDateNumber = Integer.valueOf(startDate.dayOfWeek()
.getAsString());
//Se a data final for sabado ou domingo, finja ser sexta-feira
if (dayOfWeekEndDateNumber == 6 || dayOfWeekEndDateNumber == 7) {
int DaysToAdd = 8 - dayOfWeekEndDateNumber;
endDate = endDate.plusDays(DaysToAdd);
dayOfWeekEndDateNumber = Integer.valueOf(endDate.dayOfWeek()
.getAsString());
}
//Se a data inicial for sabado ou domingo, finja ser segunda-feira
if (dayOfWeekStartDateNumber == 6 || dayOfWeekStartDateNumber == 7) {
int DaysToAdd = 8 - dayOfWeekStartDateNumber;
startDate = startDate.plusDays(DaysToAdd);
dayOfWeekStartDateNumber = Integer.valueOf(startDate.dayOfWeek()
.getAsString());
}
//Quantos dias se passaram contando os fins de semana
int days = Days.daysBetween(startDate, endDate).getDays();
//Quantas semanas se passaram exatamente
int weeks = days / 7;
//O excesso de dias que sobrou, exemplo: 1 semana e 3 dias o excess=3 e weeks=1
int excess = days % 7;
//Se a data inicial for igual a data final, passou 0 dia
if (startDate.equals(endDate)) {
return 0;
} else {
//O excesso de dias passou pelo fim de semana, então deve-se retirar 2 dias
//da quantidade final de dias
if (excess + dayOfWeekStartDateNumber >= 6) {
//Quantidade de semanas * 5 dias uteis + o excesso de dias - o final de semana que o excesso atravessou
return weeks * 5 + excess - 2;
}
//Quantidade de semanas * 5 dias uteis + o excesso de dias
return weeks * 5 + excess;
}
}
为了改进@samir machado de oliveira发布的内容,这里有一个函数可以不使用循环计算无周末的天数。我没有将其与循环版本进行基准测试,但它似乎会更快:
/**
* Gets number of days between two dates. Ignoring weekends.
* @param startDate
* @param endDate
* @return
*/
public static int getDaysBetweenIgnoreWeekends(DateTime startDate, DateTime endDate) {
// If the start date is equal to the closing date, spent 0 days
if (startDate.equals(endDate))
return 0;
// A number that represents the day for the start date, Monday = 1 , Tuesday = 2 , Wednesday = 3 ...
int dayOfWeekStartDateNumber = startDate.getDayOfWeek();
// If the starting date is Saturday or Sunday , pretend to be Monday
if (dayOfWeekStartDateNumber == 6 || dayOfWeekStartDateNumber == 7) {
int DaysToAdd = 8 - dayOfWeekStartDateNumber;
startDate = startDate.plusDays(DaysToAdd);
dayOfWeekStartDateNumber = Integer.valueOf(startDate.dayOfWeek().getAsString());
}
// How many days have passed counting weekends
int days = Days.daysBetween(startDate, endDate).getDays();
// How many weeks have passed
int weeks = days / 7;
// Excess days left. E.g. one week and three days the excess will be 3
int excess = days % 7;
// Excess of days spent for the weekend , then it must be removed two days
// the final number of days
if (excess + dayOfWeekStartDateNumber >= 6) {
// Week count * 5 working days + excess days - the weekend that excess crossed
return weeks * 5 + excess - 2;
}
// Weeks count * 5 working days + excess days
return weeks * 5 + excess;
}
此外,这是一个允许您忽略一天时间的版本,因此,如果开始日期是开始时间的上午11点,而结束时间是第二天上午10点,则它将显示为1天,而不是0天
/**
* Gets number of days between two dates. Ignoring weekends. Ignores Hours.
* @param startDate
* @param endDate
* @return
*/
public static int getDaysBetweenIgnoreWeekends(DateTime startDate, DateTime endDate) {
return getDaysBetweenIgnoreWeekends(startDate,endDate,true);
}
/**
* Gets number of days between two dates. Ignoring weekends.
* @param startDate
* @param endDate
* @param ignoreTimeOfDay
* @return
*/
public static int getDaysBetweenIgnoreWeekends(DateTime startDate, DateTime endDate, boolean ignoreTimeOfDay) {
// If the start date is equal to the closing date, spent 0 days
if (startDate.equals(endDate))
return 0;
if (ignoreTimeOfDay && startDate.toLocalDate().equals(endDate.toLocalDate()))
return 0;
// A number that represents the day for the start date, Monday = 1 , Tuesday = 2 , Wednesday = 3 ...
int dayOfWeekStartDateNumber = startDate.getDayOfWeek();
// If the starting date is Saturday or Sunday , pretend to be Monday
if (dayOfWeekStartDateNumber == 6 || dayOfWeekStartDateNumber == 7) {
int DaysToAdd = 8 - dayOfWeekStartDateNumber;
startDate = startDate.plusDays(DaysToAdd);
dayOfWeekStartDateNumber = Integer.valueOf(startDate.dayOfWeek().getAsString());
}
// How many days have passed counting weekends
int days;
if(ignoreTimeOfDay) {
days = Days.daysBetween(startDate.toLocalDate(), endDate.toLocalDate()).getDays();
} else {
days = Days.daysBetween(startDate, endDate).getDays();
}
// How many weeks have passed
int weeks = days / 7;
// Excess days left. E.g. one week and three days the excess will be 3
int excess = days % 7;
// Excess of days spent for the weekend , then it must be removed two days
// the final number of days
if (excess + dayOfWeekStartDateNumber >= 6) {
// Week count * 5 working days + excess days - the weekend that excess crossed
return weeks * 5 + excess - 2;
}
// Weeks count * 5 working days + excess days
return weeks * 5 + excess;
}
这将通过排除周末返回结束日期
public static Date addDaysBySkipWeekend(Date startDate, int numDays) {
Calendar dateCal = Calendar.getInstance();
dateCal.setTime(startDate);
for (int i = 0; i < numDays-1; i++) {
dateCal.add(dateCal.DATE, 1);
if(dateCal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY
|| dateCal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ){
dateCal.add(dateCal.DATE, 1);
i--;
}
}
return dateCal.getTime();
}
public静态日期adddayskipweekend(日期开始日期,整数天){
Calendar dateCal=Calendar.getInstance();
dateCal.setTime(开始日期);
对于(int i=0;i
我已经使用@Josh Maag的逻辑将近一年了,但最近发现当endDate恰好在周六时,它返回错误的值
这里是我想分享的版本,它考虑从endDate减去天,当它恰好是周六或周日时
public static int getDaysBetweenIgnoreWeekends(org.joda.time.DateTime startDate, org.joda.time.DateTime endDate, boolean ignoreTimeOfDay) {
// If the start date is equal to the closing date, spent 0 days
if (startDate.equals(endDate))
return 0;
if (ignoreTimeOfDay && startDate.toLocalDate().equals(endDate.toLocalDate()))
return 0;
// A number that represents the day for the start date, Monday = 1 , Tuesday = 2 , Wednesday = 3 ...
int dayOfWeekStartDateNumber = startDate.getDayOfWeek();
int dayOfWeekEndDateNumber = endDate.getDayOfWeek();
// If the starting date is Saturday or Sunday , pretend to be Monday
if (dayOfWeekStartDateNumber == 6 || dayOfWeekStartDateNumber == 7) {
int DaysToAdd = 8 - dayOfWeekStartDateNumber;
startDate = startDate.plusDays(DaysToAdd);
dayOfWeekStartDateNumber = Integer.valueOf(startDate.dayOfWeek().getAsString());
}
org.joda.time.DateTime effectiveEndDate = endDate;
if (dayOfWeekEndDateNumber == 6 || dayOfWeekEndDateNumber == 7) {
effectiveEndDate = endDate.minusDays(Math.abs(5 - dayOfWeekEndDateNumber));
}
// How many days have passed counting weekends
int days;
if(ignoreTimeOfDay) {
days = org.joda.time.Days.daysBetween(startDate.toLocalDate(), effectiveEndDate.toLocalDate()).getDays();
} else {
days = org.joda.time.Days.daysBetween(startDate, effectiveEndDate).getDays();
}
// How many weeks have passed
int weeks = days / 7;
// Excess days left. E.g. one week and three days the excess will be 3
int excess = days % 7;
// Excess of days spent for the weekend , then it must be removed two days
// the final number of days
if (excess + dayOfWeekStartDateNumber >= 6) {
// Week count * 5 working days + excess days - the weekend that excess crossed
return weeks * 5 + excess - 2;
}
// Weeks count * 5 working days + excess days
return weeks * 5 + excess;
}
在早期版本中,下面的代码片段减去了额外的一天。减去-2,无论结束日期是周六还是周日
if (excess + dayOfWeekStartDateNumber >= 6) {
// Week count * 5 working days + excess days - the weekend that excess crossed
return weeks * 5 + excess - 2;
}
希望有帮助 整洁地使用Java 8流:
public LocalDate[] filterWeekdaysForRange(final LocalDate start,final LocalDate end) {
return Stream.iterate(start, date -> date.plusDays(1))
.limit(ChronoUnit.DAYS.between(start, end)+1)
.filter(d->d.getDayOfWeek() != SATURDAY)
.filter(d->d.getDayOfWeek() != SUNDAY)
.toArray(LocalDate[]::new);
}
这是对此处提供的解决方案的改编:
计算天数
或获取所有日期
?我实际上是按照这些思路做了一些事情,但正在考虑测试当前日期是否为周六/周日,然后排除。。。这个逻辑非常有效。。。感谢分配。这假设周末由周六+周日组成,但并非所有国家/地区都是如此