Saltar al contenido

Obtenga el número de semanas entre dos fechas.

Intenta comprender el código correctamente antes de utilizarlo a tu proyecto y si tquieres aportar algo puedes decirlo en los comentarios.

Solución:

Es bastante fácil con joda time:

DateTime dateTime1 = new DateTime(date1);
DateTime dateTime2 = new DateTime(date2);

int weeks = Weeks.weeksBetween(dateTime1, dateTime2).getWeeks();

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

tl; dr

ChronoUnit
.WEEKS
.between(
    myJavaUtilDate_Start.toInstant().atZone( ZoneId.of( "Asia/Tokyo" ) ) , 
    myJavaUtilDate_Stop.toInstant().atZone( ZoneId.of( "Asia/Tokyo" ) ) 
)

7

java.time

El marco java.time está integrado en Java 8 y versiones posteriores. Estas nuevas clases sustituyen a las antiguas clases de fecha y hora incluidas con las primeras versiones de Java.

los java.time las clases también suplantan al exitoso framework Joda-Time. Ambos java.time y Joda-Time están dirigidos por Stephen Colbourne.

Tabla de tipos de fecha y hora en Java, tanto moderno como heredado

Instant reemplaza java.util.Date

La clase moderna Instant reemplaza la clase heredada java.util.Date. Ambos representan un momento en UTC, un punto específico en la línea de tiempo. Ambos utilizan internamente un recuento desde la misma referencia de época del primer momento de 1970 en UTC, 1970-01-01T00: 00Z. La clase anterior usa una cuenta de milisegundos, mientras que Instant utiliza una cuenta más fina de nanosegundos.

Para convertir, llame a los nuevos métodos agregados a las clases antiguas.

Instant start = myJavaUtilDateStart.toInstant() ;
Instant stop = myJavaUtilDateStop.toInstant() ;

Hagamos esto concreto con algunos valores de ejemplo.

Instant start = OffsetDateTime.of( 2020 , 1 , 23 , 15 , 30 , 0 , 0 , ZoneOffset.UTC ).toInstant();
Instant stop = OffsetDateTime.of( 2020 , 1 , 23 , 15 , 30 , 0 , 0 , ZoneOffset.UTC ).plusWeeks(7 ).toInstant();

Momentos versus fechas

Ambos de nuestros Instant los objetos representan un momento. El objetivo es contar semanas. Semanas significa días y días significa ciertas fechas en el calendario.

Así que tenemos un poco de desajuste. Para cualquier momento dado, la fecha varía en todo el mundo según la zona horaria. Unos minutos después de la medianoche en París, Francia es una nueva fecha. Mientras tanto en Montreal Québec, con varias horas de retraso, ese mismo momento sigue siendo “ayer”, la fecha anterior en el calendario. Por lo tanto, no podemos calcular directamente las semanas a partir de un par de momentos.

Primero debe decidir la zona horaria por la que desea percibir un calendario para esos momentos.

Especifique un nombre de zona horaria adecuado en el formato de Continent/Region, tal como America/Montreal, Africa/Casablanca, o Pacific/Auckland. Nunca use la abreviatura de 2-4 letras como EST o IST ya que son no true zonas horarias, no estandarizadas y ni siquiera únicas (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ; 

ZonedDateTime

Aplicar esto ZoneId para nuestro Instant objetos para ajustar en una zona horaria, produciendo un par de ZonedDateTime objetos.

ZonedDateTime startZdt = start.atZone( z ) ;
ZonedDateTime stopZdt = stop.atZone( z ) ;

ChronoUnit.WEEKS

Ahora podemos usar el ChronoUnit enumeración para calcular las semanas transcurridas.

semanas largas = ChronoUnit.WEEKS.between (startZdt, stopZdt);

Volcado a la consola.

System.out.println( "start.toString() = " + start );
System.out.println( "stop.toString() = " + stop );
System.out.println( "startZdt.toString() = " + startZdt );
System.out.println( "stopZdt.toString() = " + stopZdt );
System.out.println( "weeksCount: " + weeksCount );

Vea este código en vivo en IdeOne.com.

start.toString () = 2020-01-23T15: 30: 00Z

stop.toString () = 2020-03-12T15: 30: 00Z

startZdt.toString () = 2020-01-23T10: 30-05: 00[America/Montreal]

stopZdt.toString () = 2020-03-12T11: 30-04: 00[America/Montreal]

semanasCuenta: 7

ThreeTen-Extra

El proyecto ThreeTen-Extra agrega funcionalidad al marco java.time integrado en Java 8 y versiones posteriores.

Weeks clase

Ese proyecto incluye un Weeks clase para representar un número de semanas. No solo puede calcular, también está destinado a ser utilizado en su código como un objeto de tipo seguro. Este uso también ayuda a que su código se auto-documente.

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

Tu java.util.Date los objetos se pueden convertir fácilmente a Instant objetos, 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 pasar de Fecha a Instantáneo, llame java.util.Date::toInstant.

Weeks weeks = Weeks.between( startZdt , stopZdt );

Puedes preguntar por el número de semanas.

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

También puedes hacer mucho más.

Generar un string en formato estándar ISO 8601. los P marca el comienzo. los W indica un número de semanas.

PW7


Sobre java.time

los java.time framework está integrado en Java 8 y versiones posteriores. Estas clases suplantan a las antiguas y problemáticas clases de fecha y hora heredadas, como java.util.Date, CalendarY SimpleDateFormat.

Para obtener más información, consulte el Tutorial de Oracle. Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310.

los Joda-Time proyecto, ahora en modo de mantenimiento, aconseja la migración a las clases java.time.

Puedes intercambiar java.time objetos directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. Sin necesidad de cuerdas, sin necesidad de java.sql.* clases.

¿Dónde obtener las clases java.time?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11y posterior: parte de la API estándar de Java con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y Java SE 7
    • La mayoría de java.time la funcionalidad está respaldada a Java 6 y 7 en ThreeTen-Backport.
  • Androide
    • Versiones posteriores de implementaciones de paquetes de Android del java.time clases.
    • Para Android anterior (<26), el ThreeTenABP el proyecto se adapta ThreeTen-Backport (mencionado anteriormente). Ver Cómo usar ThreeTenABP….

Tabla de qué biblioteca java.time usar con qué versión de Java o Android

los ThreeTen-Extra el proyecto extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y más.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *