Obtenga el número de semanas entre dos fechas.

Estoy trabajando en un proyecto y tengo dos tipos en Fecha. Quiero calcular el número de semanas entre estas dos fechas. Las fechas pueden ser en años diferentes. ¿Hay alguna buena solución para esto?

He intentado implementar esto con Joda-time, que se sugirió en otros temas.

No estoy familiarizado con esta biblioteca, pero traté de hacer algo como esto:

public static int getNumberOfWeeks(Date f, Date l){ Calendar c1 = Calendar.getInstance(); Calendar c2 = Calendar.getInstance(); c1.setTime(f); c2.setTime(l); DateTime start = new DateTime(c1.YEAR, c1.MONTH, c1.DAY_OF_MONTH, 0, 0, 0, 0); DateTime end = new DateTime(c2.YEAR, c2.MONTH, c2.DAY_OF_MONTH, 0, 0, 0, 0); Interval interval = new Interval(start, end); Period p = interval.toPeriod(); return p.getWeeks(); } 

Pero esto está completamente mal … ¿Alguna sugerencia?

Es bastante fácil con el tiempo joda :

 DateTime dateTime1 = new DateTime(date1); DateTime dateTime2 = new DateTime(date2); int weeks = Weeks.weeksBetween(dateTime1, dateTime2).getWeeks(); 

Actualización de la respuesta a la cuenta para Java 8

 // TechTrip - ASSUMPTION d1 is earlier than d2 // leave that for exercise public static long getFullWeeks(Calendar d1, Calendar d2){ Instant d1i = Instant.ofEpochMilli(d1.getTimeInMillis()); Instant d2i = Instant.ofEpochMilli(d2.getTimeInMillis()); LocalDateTime startDate = LocalDateTime.ofInstant(d1i, ZoneId.systemDefault()); LocalDateTime endDate = LocalDateTime.ofInstant(d2i, ZoneId.systemDefault()); return ChronoUnit.WEEKS.between(startDate, endDate); } 

Usando la aritmética de fecha en java.util.Calendar :

 public static int getWeeksBetween (Date a, Date b) { if (b.before(a)) { return -getWeeksBetween(b, a); } a = resetTime(a); b = resetTime(b); Calendar cal = new GregorianCalendar(); cal.setTime(a); int weeks = 0; while (cal.getTime().before(b)) { // add another week cal.add(Calendar.WEEK_OF_YEAR, 1); weeks++; } return weeks; } public static Date resetTime (Date d) { Calendar cal = new GregorianCalendar(); cal.setTime(d); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); } 
 Calendar a = new GregorianCalendar(2002,1,22); Calendar b = new GregorianCalendar(2002,1,28); System.out.println(a.get(Calendar.WEEK_OF_YEAR)); System.out.println(b.get(Calendar.WEEK_OF_YEAR)); int weeks = b.get(Calendar.WEEK_OF_YEAR)-a.get(Calendar.WEEK_OF_YEAR); System.out.println(weeks); 

prueba esto debe funcionar

  Calendar calendar1 = Calendar.getInstance(); Calendar calendar2 = Calendar.getInstance(); calendar1.set(2007, 01, 10); calendar2.set(2007, 07, 01); long milliseconds1 = calendar1.getTimeInMillis(); long milliseconds2 = calendar2.getTimeInMillis(); long diff = milliseconds2 - milliseconds1; int diffWeeks = (int)diff / (7*24 * 60 * 60 * 1000); 

Eche un vistazo al siguiente artículo: Java: calcule la diferencia entre dos fechas

El método daysBetween le permitirá obtener el número de días entre las fechas. Luego puedes dividir por 7 para obtener el número de semanas completas.

  Calendar date1 = Calendar.getInstance(); Calendar date2 = Calendar.getInstance(); date1.clear(); date1.set(datePicker1.getYear(), datePicker1.getMonth(), datePicker1.getDayOfMonth()); date2.clear(); date2.set(datePicker2.getYear(), datePicker2.getMonth(), datePicker2.getDayOfMonth()); long diff = date2.getTimeInMillis() - date1.getTimeInMillis(); float dayCount = (float) diff / (24 * 60 * 60 * 1000); int week = (dayCount / 7) ; 

Espero que esto te ayude

Puedes hacerlo de la siguiente manera:

 // method header not shown // example dates: f = new GregorianCalendar(2009,Calendar.AUGUST,1); l = new GregorianCalendar(2010,Calendar.SEPTEMBER,1); DateTime start = new DateTime(f); DateTime end = new DateTime(l); // Alternative to above - example dates with joda: // DateTime start = new DateTime(2009,8,1,0,0,0,0); // DateTime end = new DateTime(2010,9,1,0,0,0,0); Interval interval = new Interval(start,end); int weeksBetween = interval.toPeriod(PeriodType.weeks()).getWeeks(); // return weeksBetween; 

Esto debería darle un int que representa el número de semanas entre las dos fechas.

Joda Time calcula semanas con duraciones de dos fechas que pueden no cumplir con nuestros requisitos en algunos casos. Tengo un método con Joda Time para calcular semanas naturales entre dos fechas. Espero que te ayude. Si no utiliza Joda Time, puede modificar el código con Calendar para hacer lo mismo.

 //Unlike Joda Time Weeks.weeksBetween() that returns whole weeks computed //from duration, we return natural weeks between two dates based on week of year public static int weeksBetween(ReadablePartial date1, ReadablePartial date2) { int comp = date1.compareTo(date2); if (comp == 0) { return 0; } if (comp > 0) { ReadablePartial mid = date2; date2 = date1; date1 = mid; } int year1 = date1.get(DateTimeFieldType.weekyear()); int year2 = date2.get(DateTimeFieldType.weekyear()); if (year1 == year2) { return date2.get(DateTimeFieldType.weekOfWeekyear()) - date1.get(DateTimeFieldType.weekOfWeekyear()); } int weeks1 = 0; LocalDate lastDay1 = new LocalDate(date1.get(DateTimeFieldType.year()), 12, 31); if (lastDay1.getWeekyear() > year1) { lastDay1 = lastDay1.minusDays(7); weeks1++; } weeks1 += lastDay1.getWeekOfWeekyear() - date1.get(DateTimeFieldType.weekOfWeekyear()); int midWeeks = 0; for (int i = year1 + 1; i < year2; i++) { LocalDate y1 = new LocalDate(i, 1, 1); int yearY1 = y1.getWeekyear(); if (yearY1 < i) { y1 = y1.plusDays(7); midWeeks++; } LocalDate y2 = new LocalDate(i, 12, 31); int yearY2 = y2.getWeekyear(); if (yearY2 > i) { y2 = y2.minusDays(7); midWeeks++; } midWeeks += y2.getWeekOfWeekyear() - y1.getWeekOfWeekyear(); } int weeks2 = 0; LocalDate firstDay2 = new LocalDate(date2.get(DateTimeFieldType.year()), 1, 1); if (firstDay2.getWeekyear() < firstDay2.getYear()) { firstDay2 = firstDay2.plusDays(7); weeks2++; } weeks2 += date2.get(DateTimeFieldType.weekOfWeekyear()) - firstDay2.getWeekOfWeekyear(); return weeks1 + midWeeks + weeks2; } 
  int startWeek = c1.get(Calendar.WEEK_OF_YEAR); int endWeek = c2.get(Calendar.WEEK_OF_YEAR); int diff = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR); int deltaYears = 0; for(int i = 0;i < diff;i++){ deltaYears += c1.getWeeksInWeekYear(); c1.add(Calendar.YEAR, 1); } diff = (endWeek + deltaYears) - startWeek; 

Incluye las diferencias del año. Esto funcionó para mí 🙂

 private int weeksBetween(Calendar startDate, Calendar endDate) { startDate.set(Calendar.HOUR_OF_DAY, 0); startDate.set(Calendar.MINUTE, 0); startDate.set(Calendar.SECOND, 0); int start = (int)TimeUnit.MILLISECONDS.toDays( startDate.getTimeInMillis()) - startDate.get(Calendar.DAY_OF_WEEK); int end = (int)TimeUnit.MILLISECONDS.toDays( endDate.getTimeInMillis()); return (end - start) / 7; } 

si este método devuelve 0, están en la misma semana

si este método devuelve 1 endDate es la semana posterior a startDate

si este método devuelve -1 endDate es la semana anterior a startDate

tienes la idea

java.time

El marco java.time está integrado en Java 8 y posterior. Estas nuevas clases suplantan a las antiguas clases de fecha y hora incluidas con las primeras versiones de Java. Estas clases también suplantan al exitoso framework Joda-Time , y son construidas por las mismas personas, incluyendo el liderazgo de Stephen Colbourne .

ThreeTen-Extra

El proyecto ThreeTen-Extra es la extensión oficial del marco java.time integrado en Java 8 y posterior. Este proyecto es el campo de pruebas para posibles adiciones futuras a java.time, y está destinado a ser útil por derecho propio.

Clase de Weeks

Ese proyecto incluye una clase de Weeks para representar un número de semanas. No solo puede calcular, sino que también debe usarse en su código como un objeto seguro para tipos. Tal uso también ayuda a que su código se auto-documente.

Puede crear instancias proporcionando un par de puntos en el tiempo con el método Weeks.between . Esos puntos en el tiempo pueden ser cualquier cosa que implemente java.time.temporal.Temporal incluyendo Instant , LocalDate , OffsetDateTime , ZonedDateTime , Year , YearMonth , y más.

Sus objetos java.util.Date se pueden convertir fácilmente en objetos Instant , momentos en la línea de tiempo en UTC con una resolución en nanosegundos. Mire los nuevos métodos agregados a las antiguas clases de fecha y hora. Para ir de Date to Instant, llame a java.util.Date::toInstant .

 Instant start = utilDateStart.toInstant(); Instant stop = utilDateStop.toInstant(); Weeks weeks = Weeks.between( start , stop ); 

Puede solicitar el número de semanas. También puedes hacer mucho más.

 int weeksNumber = weeks.getAmount(); // The number of weeks in this Weeks object. 

Si desea el número exacto de semanas completas, utilice el siguiente método, donde la fecha de finalización es exclusiva:

 public static long weeksBetween(Date date1, Date date2) { return WEEKS.between(date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); } 

Si quieres una versión ceil de esto, utiliza a continuación:

 public static long weeksBetween(Date date1, Date date2) { long daysBetween = DAYS.between(date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) + 1; return daysBetween / 7 + (daysBetween % 7 == 0 ? 0 : 1); }