tiempo restar meses manualmente horas fechas entre dias calcular años java datetime jodatime

java - restar - calcular tiempo entre dos fechas excel



Cálculo de fechas dadas dos fechas excluyendo el fin de semana (6)

Estoy usando Joda time api en un proyecto de Spring 3.0 para calcular las fechas. Ahora tengo una fecha de inicio y finalización y quiero tener todos los fines de semana de fin de semana o sábado o domingo entre estas dos fechas. Cómo puedo conseguir esto ?

Miré esta publicación Joda time - todos los lunes entre dos fechas . Ofreció alguna orientación, pero todavía es vaga como la forma de excluir dos fechas.


Puede usar el calendario gregoriano para recuperar el día de una fecha determinada. Si la cadena es sábado o domingo, puede descuidarla.


Supongo que tu pregunta es cómo

obtener todos los días excepto el fin de semana o el sábado o el domingo entre dos fechas.

Solución :

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); } }


Soy nuevo aqui. He estado buscando una solución a este problema y no he usado un bucle pero no he encontrado un algoritmo adecuado. Así que decidí crear esta solución que no utiliza bucle, es muy eficiente y el código ha sido probado.

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; } }


Esto devolverá la fecha de finalización excluyendo los fines de semana

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(); }


Para mejorar lo que @ samir-machado-de-oliveira publicó, aquí hay una función que calculará los días sin fines de semana sin usar un bucle. No comparé esto con la versión en bucle, pero parece que sería más rápido:

/** * 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; }

Además, aquí hay una versión que le permitirá ignorar la hora del día, de modo que si la fecha de inicio es a las 11AM en la hora de inicio y la hora de finalización es el día siguiente a las 10AM, se mostrará como 1 día en lugar de 0 dias.

/** * 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; }


He estado utilizando la lógica de @Josh Maag durante casi un año pero recientemente descubrí que devuelve un valor incorrecto cuando endDate cae un sábado.

Aquí está la versión que me gustaría compartir que considera restar días de endDate cuando es sábado o domingo.

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; }

En la versión anterior, el fragmento siguiente restaba un día adicional. Restando -2 no importa si endDate fue un sábado o domingo.

if (excess + dayOfWeekStartDateNumber >= 6) { // Week count * 5 working days + excess days - the weekend that excess crossed return weeks * 5 + excess - 2; }

¡Espero que ayude!