transcurridos restar meses horas formato fechas entre ejemplo diferencia dias calcular años java date java-8 java-time

restar - Java 8 LocalDate: ¿cómo obtengo todas las fechas entre dos fechas?



localdate java ejemplo (9)

tl; dr

Ampliando la buena respuesta de Singh , utilizando una secuencia de datesUntil en Java 9 y posterior.

today // Determine your beginning `LocalDate` object. .datesUntil( // Generate stream of `LocalDate` objects. today.plusMonths( 1 ) // Calculate your ending date, and ask for a stream of dates till then. ) // Returns the stream. .collect( Collectors.toList() ) // Collect your resulting dates in a `List`. .toString() // Generate text representing your found dates.

[2018-09-20, 2018-09-21, 2018-09-22, 2018-09-23, 2018-09-24, 2018-09-25, 2018-09-26, 2018-09-27, 2018 -09-28, 2018-09-29, 2018-09-30, 2018-10-01, 2018-10-02, 2018-10-03, 2018-10-04, 2018-10-05, 2018-10 -06, 2018-10-07, 2018-10-08, 2018-10-09, 2018-10-10, 2018-10-11, 2018-10-12, 2018-10-13, 2018-10-14 , 2018-10-15, 2018-10-16, 2018-10-17, 2018-10-18, 2018-10-19]

LocalDate::datesUntil stream

A partir de Java 9, puede solicitar una secuencia de fechas. Llame a datesUntil .

Comience por determinar la fecha de hoy. Eso requiere una zona horaria. Para cualquier momento, la fecha varía en todo el mundo por zona.

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ; LocalDate today = LocalDate.now( z ) ;

Determina tu fecha de finalización.

LocalDate stop = today.plusMonths( 1 ) ;

Solicite una secuencia de fechas de principio a fin.

Stream< LocalDate > stream = today.datesUntil( today.plusMonths( 1 ) );

Extraiga las fechas de esa secuencia, reuniéndolas en una List .

List< LocalDate > datesForMonthFromToday = stream.collect( Collectors.toList() );

Imprima nuestra lista de fechas, generando texto en formato estándar ISO 8601 .

System.out.println( datesForMonthFromToday );

Sobre java.time

El marco java.time está integrado en Java 8 y java.time posteriores. Estas clases suplantan a las antiguas y problemáticas clases de fecha y hora legacy , como java.util.Date , Calendar y SimpleDateFormat .

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

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 .

Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No necesita cadenas, no necesita clases java.sql.* .

¿Dónde obtener las clases java.time?

El proyecto ThreeTen-Extra 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 more .

¿Existe una usabilidad para obtener todas las fechas entre dos fechas en la nueva API java.time ?

Digamos que tengo esta parte del código:

@Test public void testGenerateChartCalendarData() { LocalDate startDate = LocalDate.now(); LocalDate endDate = startDate.plusMonths(1); endDate = endDate.withDayOfMonth(endDate.lengthOfMonth()); }

Ahora necesito todas las fechas entre startDate y endDate .

Estaba pensando en obtener los daysBetween entre las dos fechas e iterar sobre:

long daysBetween = ChronoUnit.DAYS.between(startDate, endDate); for(int i = 0; i <= daysBetween; i++){ startDate.plusDays(i); //...do the stuff with the new date... }

¿Hay una mejor manera de obtener las fechas?


En mi biblioteca de tiempo Time4J , he escrito un spliterator optimizado para construir una secuencia de fechas de calendario con buenas características de paralelización. Adaptado a su caso de uso:

LocalDate start = ...; LocalDate end = ...; Stream<LocalDate> stream = DateInterval.between(start, end) // closed interval, else use .withOpenEnd() .streamDaily() .map(PlainDate::toTemporalAccessor);

Este breve enfoque puede ser un punto de partida interesante si también está interesado en características relacionadas como intervalos de reloj por fecha de calendario (secuencias particionadas) u otras características de intervalo y desea evitar el código incómodo escrito a mano, consulte también la API de DateInterval .


La biblioteca ThreeTen-Extra tiene una clase LocalDateRange que puede hacer exactamente lo que está solicitando:

LocalDateRange.ofClosed(startDate, endDate).stream() .forEach(/* ...do the stuff with the new date... */);


Primero puede usar un TemporalAdjuster para obtener el último día del mes. A continuación, Stream API ofrece Stream::iterate que es la herramienta adecuada para su problema.

LocalDate start = LocalDate.now(); LocalDate end = LocalDate.now().plusMonths(1).with(TemporalAdjusters.lastDayOfMonth()); List<LocalDate> dates = Stream.iterate(start, date -> date.plusDays(1)) .limit(ChronoUnit.DAYS.between(start, end)) .collect(Collectors.toList()); System.out.println(dates.size()); System.out.println(dates);


Puede crear una stream de objetos LocalDate . También tuve este problema y publiqué mi solución como java-timestream en github.

Usando tu ejemplo ...

LocalDateStream .from(LocalDate.now()) .to(1, ChronoUnit.MONTHS) .stream() .collect(Collectors.toList());

Es más o menos equivalente a otras soluciones propuestas aquí, pero se encarga de todas las matemáticas de fechas y saber cuándo parar. Puede proporcionar fechas de finalización específicas o relativas y decirle cuánto tiempo omitir cada iteración (el valor predeterminado anterior es un día).


Puede usar .isAfter y .plusDays para hacer esto en un bucle. No diría mejor, ya que no he investigado mucho sobre el tema, pero puedo decir con confianza que usa la API de Java 8 y es una pequeña alternativa.

LocalDate startDate = LocalDate.now(); LocalDate endDate = startDate.plusMonths(1); while (!startDate.isAfter(endDate)) { System.out.println(startDate); startDate = startDate.plusDays(1); }

Salida

2016-07-05 2016-07-06 ... 2016-08-04 2016-08-05

Ejemplo aquí


Puede usar la funcionalidad Range en la biblioteca Guava de Google. Después de definir el DiscreteDomain sobre LocalDate instancias LocalDate , puede obtener un ContiguousSet de todas las fechas en el rango.

LocalDate d1 = LocalDate.parse("2017-12-25"); LocalDate d2 = LocalDate.parse("2018-01-05"); DiscreteDomain<LocalDate> localDateDomain = new DiscreteDomain<LocalDate>() { public LocalDate next(LocalDate value) { return value.plusDays(1); } public LocalDate previous(LocalDate value) { return value.minusDays(1); } public long distance(LocalDate start, LocalDate end) { return start.until(end, ChronoUnit.DAYS); } public LocalDate minValue() { return LocalDate.MIN; } public LocalDate maxValue() { return LocalDate.MAX; } }; Set<LocalDate> datesInRange = ContiguousSet.create(Range.closed(d1, d2), localDateDomain);


Suponiendo que principalmente desea iterar sobre el rango de fechas, tendría sentido crear una clase DateRange que sea iterable. Eso te permitiría escribir:

for (LocalDate d : DateRange.between(startDate, endDate)) ...

Algo como:

public class DateRange implements Iterable<LocalDate> { private final LocalDate startDate; private final LocalDate endDate; public DateRange(LocalDate startDate, LocalDate endDate) { //check that range is valid (null, start < end) this.startDate = startDate; this.endDate = endDate; } @Override public Iterator<LocalDate> iterator() { return stream().iterator(); } public Stream<LocalDate> stream() { return Stream.iterate(startDate, d -> d.plusDays(1)) .limit(ChronoUnit.DAYS.between(startDate, endDate) + 1); } public List<LocalDate> toList() { //could also be built from the stream() method List<LocalDate> dates = new ArrayList<> (); for (LocalDate d = startDate; !d.isAfter(endDate); d = d.plusDays(1)) { dates.add(d); } return dates; } }

Tendría sentido agregar métodos igual y hashcode, getters, tal vez tener una fábrica estática + constructor privado para que coincida con el estilo de codificación de la API de tiempo de Java, etc.


Java 9

En Java 9, la clase LocalDate se mejoró con el método LocalDate.datesUntil (LocalDate endExclusive) , que devuelve todas las fechas dentro de un rango de fechas como Stream<LocalDate> .

List<LocalDate> dates = startDate.datesUntil(endDate).collect(Collectors.toList());