java - otras - saber si una fecha esta dentro de un rango c#
Java: ¿cómo puedo verificar si una fecha está dentro de un cierto rango? (11)
Tengo una serie de rangos con fechas de inicio y 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 así como este pseudocódigo:
boolean isWithinRange(Date testDate) {
return testDate >= startDate && testDate <= endDate;
}
No estoy seguro si es relevante, pero las fechas que estoy sacando de la base de datos tienen marcas de tiempo.
tl; dr
ZoneId z = ZoneId.of( "America/Montreal" ); // A date only has meaning within a specific time zone. For 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-hora comúnmente emplea el enfoque "medio abierto" para definir un lapso de tiempo. El comienzo es inclusivo, mientras que el final es exclusivo . Entonces, una semana que comienza el lunes corre hasta, pero no incluye, el lunes siguiente.
java.time
Java 8 y java.time posteriores vienen con el framework java.time incorporado. Suplanta las antiguas clases problemáticas, incluidas java.util.Date/.Calendar y SimpleDateFormat. Inspirado por 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 una resolución de nanosegundos.
Instant
Convierte tus objetos java.util.Date a objetos Instantáneos.
Instant start = myJUDateStart.toInstant();
Instant stop = …
Si obtiene objetos java.sql.Timestamp a través de JDBC desde una base de datos, conviértelos a java.time.Instant de forma similar. Una 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 la comparación.
Instant now = Instant.now();
Compare usando 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.
La clase LocalDate
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. Para 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 los isEqual
, isBefore
y isAfter
para comparar. En el trabajo de fecha y hora, comúnmente utilizamos el enfoque de Medio Abierto, 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 elige agregar la biblioteca ThreeTen-Extra a su proyecto, puede usar la clase Interval
para definir un lapso de tiempo. Esa clase ofrece métodos para probar si el intervalo contains , encloses , encloses o se overlaps otras fechas / intervalos de tiempo.
La clase Interval
funciona en objetos Instant
. La clase Instant
representa un momento en la línea de tiempo en UTC con una resolución de nanoseconds (hasta nueve (9) dígitos de una fracción decimal).
Podemos ajustar LocalDate
en un momento específico, el primer momento del día, especificando un huso horario 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
El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases legacy fecha y hora como java.util.Date
, java.util.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 para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
¿Dónde obtener las clases de java.time?
- Java SE 8 y SE 9 y posteriores
- Incorporado.
- Parte de la API Java estándar con una implementación integrada.
- Java 9 agrega algunas características y correcciones menores.
- Java SE 6 y SE 7
- Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
- Android
- El proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente) específicamente para Android.
- Vea Cómo usar ...
El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval
, YearWeek
, YearQuarter
y more .
Considera usar Joda Time . Me encanta esta biblioteca y desearía que reemplazara el horrible desastre actual que son las clases Java Date y Calendar. Es el manejo de la fecha hecho bien.
EDITAR: Ya no es 2009, y Java 8 ha estado fuera por mucho tiempo. Use Java 8''s en las clases java.time que se basan en Joda Time, como Basil Bourque menciona a continuación. En este caso, querrá la clase Period, y aquí está el tutorial de Oracle sobre cómo usarlo.
Esa es la forma correcta. Los calendarios funcionan de la misma manera. Lo mejor que puedo ofrecerte (basado en tu ejemplo) es este:
boolean isWithinRange(Date testDate) {
return testDate.getTime() >= startDate.getTime() &&
testDate.getTime() <= endDate.getTime();
}
Date.getTime () devuelve la cantidad de milisegundos desde 1/1/1970 00:00:00 GMT, y es larga, por lo que es fácilmente comparable.
Esto fue más claro para mí,
// declare calendar outside the scope of isWithinRange() so that we initialize it only once
private Calendar calendar = Calendar.getInstance();
public boolean isWithinRange(Date date, Date startDate, Date endDate) {
calendar.setTime(startDate);
int startDayOfYear = calendar.get(Calendar.DAY_OF_YEAR); // first day is 1, last day is 365
int startYear = calendar.get(Calendar.YEAR);
calendar.setTime(endDate);
int endDayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
int endYear = calendar.get(Calendar.YEAR);
calendar.setTime(date);
int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
int year = calendar.get(Calendar.YEAR);
return (year > startYear && year < endYear) // year is within the range
|| (year == startYear && dayOfYear >= startDayOfYear) // year is same as start year, check day as well
|| (year == endYear && dayOfYear < endDayOfYear); // year is same as end year, check day as well
}
No me importa qué fecha es el límite.
Math.abs(date1.getTime() - date2.getTime()) ==
Math.abs(date1.getTime() - dateBetween.getTime()) + Math.abs(dateBetween.getTime() - date2.getTime());
No veo la razón para hacer esto en Java cuando puedes hacerlo con una simple instrucción SQL.
Al igual que en esta Pregunta / Respuesta:
Consulta Postgresql entre intervalos de fechas
SELECT
user_id
FROM
user_logs
WHERE
login_date >= ''2014-02-01''
AND login_date < ''2014-03-01''
Simplemente adáptese a sus necesidades y termine. Algo como:
SELECT
testdate
FROM
dates
WHERE
testdate BETWEEN startdate AND duedate
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.
puedes usar esto
Interval interval = new Interval(date1.getTime(),date2.getTime());
Interval interval2 = new Interval(date3.getTime(), date4.getTime());
Interval overlap = interval.overlap(interval2);
boolean isOverlap = overlap == null ? false : true
tu lógica funcionaría bien Como mencionó las fechas que obtiene de la base de datos están en la marca de tiempo, solo necesita convertir primero la marca de tiempo en la fecha y luego usar esta lógica.
Tampoco te olvides de verificar las fechas nulas.
aquí m compartiendo un poco para convertir de Timestamp a fecha.
public static Fecha convertTimeStamptoDate (String val) throws Excepción {
DateFormat df = null;
Date date = null;
try {
df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
date = df.parse(val);
// System.out.println("Date Converted..");
return date;
} catch (Exception ex) {
System.out.println(ex);
return convertDate2(val);
} finally {
df = null;
date = null;
}
}
public class TestDate {
public static void main(String[] args) {
// TODO Auto-generated method stub
String fromDate = "18-FEB-2018";
String toDate = "20-FEB-2018";
String requestDate = "19/02/2018";
System.out.println(checkBetween(requestDate,fromDate, toDate));
}
public static boolean checkBetween(String dateToCheck, String startDate, String endDate) {
boolean res = false;
SimpleDateFormat fmt1 = new SimpleDateFormat("dd-MMM-yyyy"); //22-05-2013
SimpleDateFormat fmt2 = new SimpleDateFormat("dd/MM/yyyy"); //22-05-2013
try {
Date requestDate = fmt2.parse(dateToCheck);
Date fromDate = fmt1.parse(startDate);
Date toDate = fmt1.parse(endDate);
res = requestDate.compareTo(fromDate) >= 0 && requestDate.compareTo(toDate) <=0;
}catch(ParseException pex){
pex.printStackTrace();
}
return res;
}
}
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.