Tengo una serie de rangos con fechas de inicio y fechas de finalización. Quiero verificar si una fecha está dentro de ese rango.
Date.before() y Date.after() parecen ser un poco incómodos de usar. Lo que realmente necesito es algo como este pseudocódigo:
boolean isWithinRange(Date testDate) {
return testDate >= startDate && testDate <= endDate;
}
No estoy seguro de si es relevante, pero las fechas que extraigo de la base de datos tienen marcas de tiempo.
boolean isWithinRange(Date testDate) {
return !(testDate.before(startDate) || testDate.after(endDate));
}
No me parece tan incómodo. Tenga en cuenta que lo escribí de esa manera en lugar de
return testDate.after(startDate) && testDate.before(endDate);
por lo que funcionaría incluso si testDate fuera exactamente igual a uno de los casos finales.
tl; dr
ZoneId z = ZoneId.of( "America/Montreal" ); // A date only has meaning within a specific time zone. At any given moment, the date varies around the globe by zone.
LocalDate ld =
givenJavaUtilDate.toInstant() // Convert from legacy class `Date` to modern class `Instant` using new methods added to old classes.
.atZone( z ) // Adjust into the time zone in order to determine date.
.toLocalDate(); // Extract date-only value.
LocalDate today = LocalDate.now( z ); // Get today’s date for specific time zone.
LocalDate kwanzaaStart = today.withMonth( Month.DECEMBER ).withDayOfMonth( 26 ); // Kwanzaa starts on Boxing Day, day after Christmas.
LocalDate kwanzaaStop = kwanzaaStart.plusWeeks( 1 ); // Kwanzaa lasts one week.
Boolean isDateInKwanzaaThisYear = (
( ! today.isBefore( kwanzaaStart ) ) // Short way to say "is equal to or is after".
&&
today.isBefore( kwanzaaStop ) // Half-Open span of time, beginning inclusive, ending is *exclusive*.
)
Medio abierto
El trabajo de fecha y hora comúnmente emplea el enfoque “Medio abierto” para definir un lapso de tiempo. el principio es inclusivo mientras que el final es exclusivo. Entonces, una semana que comienza un lunes termina, pero no incluye, el lunes siguiente.
java.tiempo
Java 8 y posteriores vienen con el java.time
marco incorporado. Reemplaza las viejas clases problemáticas que incluyen java.util.Date/.Calendar
y SimpleDateFormat
. Inspirado en la exitosa biblioteca Joda-Time. Definido por JSR 310. Extendido por el proyecto ThreeTen-Extra.
Un Instant
es un momento en la línea de tiempo en UTC con resolución de nanosegundos.
Instant
Convierte tu java.util.Date
objetos a objetos instantáneos.
Instant start = myJUDateStart.toInstant();
Instant stop = …
si conseguir java.sql.Timestamp
objetos a través de JDBC desde una base de datos, convertir a java.time.Instant en una manera similar. UN java.sql.Timestamp
ya está en UTC, por lo que no debe preocuparse por las zonas horarias.
Instant start = mySqlTimestamp.toInstant() ;
Instant stop = …
Obtenga el momento actual para comparar.
Instant now = Instant.now();
Compare utilizando los métodos isBefore, isAfter y equals.
Boolean containsNow = ( ! now.isBefore( start ) ) && ( now.isBefore( stop ) ) ;
LocalDate
Tal vez quiera trabajar solo con la fecha, no con la hora del día.
Él LocalDate
class representa un valor de solo fecha, sin hora del día y sin zona horaria.
LocalDate start = LocalDate.of( 2016 , 1 , 1 ) ;
LocalDate stop = LocalDate.of( 2016 , 1 , 23 ) ;
Para obtener la fecha actual, especifique una zona horaria. En cualquier momento dado, la fecha de hoy varía según la zona horaria. Por ejemplo, un nuevo día amanece antes en París que en Montreal.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
Podemos usar el isEqual
, isBefore
y isAfter
Métodos para comparar. En el trabajo de fecha y hora, comúnmente usamos el enfoque semiabierto donde el comienzo de un lapso de tiempo es inclusivo mientras que el final es exclusivo.
Boolean containsToday = ( ! today.isBefore( start ) ) && ( today.isBefore( stop ) ) ;
Interval
Si opta por agregar el ThreeTen-Extra biblioteca a su proyecto, puede usar el Interval
clase para definir un lapso de tiempo. Esa clase ofrece métodos para probar si el intervalo contiene, linda, encierrao se superpone otras fechas-horas/intervalos.
Él Interval
la clase trabaja en Instant
objetos. Él Instant
clase representa un momento en la línea de tiempo en UTC con resolución de nanosegundos (hasta nueve (9) dígitos de una fracción decimal).
Podemos ajustar el LocalDate
en un momento específico, el primer momento del día, especificando una zona horaria para obtener un ZonedDateTime
. Desde allí podemos volver a UTC extrayendo un Instant
.
ZoneId z = ZoneId.of( "America/Montreal" );
Interval interval =
Interval.of(
start.atStartOfDay( z ).toInstant() ,
stop.atStartOfDay( z ).toInstant() );
Instant now = Instant.now();
Boolean containsNow = interval.contains( now );
Acerca de java.time
Él java.tiempo framework está integrado en Java 8 y versiones posteriores. Estas clases suplantan a las viejas y problemáticas legado clases de fecha y hora como java.util.Date
, Calendar
& SimpleDateFormat
.
Él Joda-Tiempo proyecto, ahora en modo de mantenimientoaconseja la migración a la java.time
clases
Para obtener más información, consulte la Tutorial de oráculo. Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310.
Dónde obtener el java.time
clases?
- Java SE 8 y SE 9 y después
- Incorporado.
- Parte de la API de Java estándar con una implementación integrada.
- Java 9 agrega algunas características y correcciones menores.
- Java SE 6 y SE 7
- Mucho de
java.time
la funcionalidad está adaptada a Java 6 y 7 en ThreeTen-Backport.
- Androide
- Él TresDiezABP el proyecto se adapta ThreeTen-Backport (mencionado anteriormente) para Android específicamente.
- Ver Cómo utilizar….
Él ThreeTen-Extra el proyecto se extiende java.time
con clases adicionales. Este proyecto es un campo de pruebas para posibles futuras adiciones a java.time
. Puede encontrar algunas clases útiles aquí, como Interval
, YearWeek
, YearQuarter
y más.
Esa es la forma correcta. Los calendarios funcionan de la misma manera. Lo mejor que podría ofrecerle (basado en su ejemplo) es esto:
boolean isWithinRange(Date testDate) {
return testDate.getTime() >= startDate.getTime() &&
testDate.getTime() <= endDate.getTime();
}
Date.getTime() devuelve el número de milisegundos desde el 1/1/1970 a las 00:00:00 GMT, y es largo, por lo que es fácilmente comparable.
Considere usar hora joda. Me encanta esta biblioteca y desearía que reemplazara el horrible desastre actual que son las clases Java Date y Calendar existentes. Es el manejo de fechas bien hecho.
EDITAR: ya no es 2009, y Java 8 ha estado fuera durante mucho tiempo. Utilice las clases java.time integradas de Java 8 que se basan en Joda Time, como menciona anteriormente Basil Bourque. En este caso, querrá la clase Período, y aquí está tutorial de oracle sobre cómo usarlo.
Una manera fácil es convertir las fechas en milisegundos después del 1 de enero de 1970 (use Date.getTime()) y luego compare estos valores.
Ya que Java 8
NOTA: Todos menos uno Date
Los constructores están en desuso. La mayoría de Date
Los métodos de están en desuso. ÁRBITRO: Fecha: métodos obsoletos. Todo pero Date::from(Instant)
los métodos estáticos están en desuso.
Entonces, desde Java 8 considere usar Instant
(inmutable, seguro para subprocesos, consciente de los segundos intercalares) escriba en lugar de Date
. ÁRBITRO: Instante
static final LocalTime MARKETS_OPEN = LocalTime.of(07, 00);
static final LocalTime MARKETS_CLOSE = LocalTime.of(20, 00);
// Instant utcTime = testDate.toInstant();
var bigAppleTime = ZonedDateTime.ofInstant(utcTime, ZoneId.of("America/New_York"));
dentro de la gama INCLUYE:
return !bigAppleTime.toLocalTime().isBefore(MARKETS_OPEN)
&& !bigAppleTime.toLocalTime().isAfter(MARKETS_CLOSE);
dentro de la gama EXCLUSIVA:
return bigAppleTime.toLocalTime().isAfter(MARKETS_OPEN)
&& bigAppleTime.toLocalTime().isBefore(MARKETS_CLOSE);
si quieres una comparación inclusiva con LocalDate
entonces usa este código.
LocalDate from = LocalDate.of(2021,8,1);
LocalDate to = LocalDate.of(2021,8,1);
LocalDate current = LocalDate.of(2021,8,1);
boolean isDateInRage = ( ! (current.isBefore(from.minusDays(1)) && current.isBefore(to.plusDays(1))) );
Pregunta similar con múltiples respuestas: ¿Cómo puedo determinar si una fecha está entre dos fechas en Java?
– Basil Bourque
9 de febrero de 2016 a las 18:47
FYI, las viejas y problemáticas clases de fecha y hora como
java.util.Date
yjava.util.Calendar
son ahora legadosuplantado por el java.tiempo clases Ver Tutorial de Oracle.– Basil Bourque
4 sep 2017 a las 22:56