Saltar al contenido

Vea si la hora actual se encuentra dentro de un rango de tiempo específico en el día actual en Java

Te damos la bienvenida a nuestra web, aquí vas a hallar la resolución a lo que buscas.

Solución:

esto es todo lo que debe hacer, este método está débilmente acoplado a la entrada y es muy coherente.

boolean isNowBetweenDateTime(final Date s, final Date e)

    final Date now = new Date();
    return now.after(s) && now.before(e);

cómo se obtienen los objetos de fecha para el inicio y el final es irrelevante para compararlos. Estás haciendo las cosas mucho más complicadas de lo necesario al pasar String representaciones alrededor.

Aquí hay una mejor manera de obtener las fechas de inicio y finalización, de nuevo poco acopladas y muy coherentes.

private Date dateFromHourMinSec(final String hhmmss)

    if (hhmmss.matches("^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$"))
    
        final String[] hms = hhmmss.split(":");
        final GregorianCalendar gc = new GregorianCalendar();
        gc.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hms[0]));
        gc.set(Calendar.MINUTE, Integer.parseInt(hms[1]));
        gc.set(Calendar.SECOND, Integer.parseInt(hms[2]));
        gc.set(Calendar.MILLISECOND, 0);
        return gc.getTime();
    
    else
    
        throw new IllegalArgumentException(hhmmss + " is not a valid time, expecting HH:MM:SS format");
    

Ahora puede realizar dos llamadas a métodos bien nombrados que serán bastante autodocumentados.

Como lo señaló Kevin, Fuzzy Lollipop’s Regex no recogerá los horarios entre las 14:00 y las 19:00.

Para igualar un reloj completo de 24 horas, puede usar esto:

if (hhmmss.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"))

    // Do stuff here

tl; dr

LocalTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
                             .toLocalTime() ;
Boolean isBetween = ( ! now.isBefore( LocalTime.of( 18 , 0 ) )  // "not before" means "is equal to OR after".
                    && 
                    now.isBefore( LocalTime.of( 18 , 30 ) ) ;  // Half-Open, beginning is *inclusive* while ending is *exclusive*.

Usando java.time

Está utilizando clases antiguas de fecha y hora que han demostrado estar mal diseñadas, ser confusas y problemáticas. Ahora son heredados, reemplazados por las clases java.time.

LocalTime

No pase meras cadenas que representen valores de hora del día. Ahora tenemos un tipo para eso, el LocalTime clase.

LocalTime start = LocalTime.of( 18 , 0 );
LocalTime stop = LocalTime.of( 18 , 30 );

Pase esas instancias a su método de utilidad. Ese método no debería tener que realizar ningún análisis, por lo que no es necesario lanzar la excepción de análisis.

public static  boolean isCurrentTimeBetween( LocalTime start , LocalTime stop ) {
…

ZonedDateTime

Una zona horaria es fundamental para determinar la fecha y la hora actuales. Para un momento dado, la fecha varía en todo el mundo según la zona. Por ejemplo, unos minutos después de la medianoche en París, Francia es un nuevo día, mientras que todavía es “ayer” en Montréal Québec.

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 3-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 zdt = ZonedDateTime.now( z );

Para comparar la hora del día de ahora, simplemente podríamos extraer un LocalTime a partir de ese ZonedDateTime. Pero tenemos el problema de las anomalías, como el horario de verano (DST) y los políticos que redefinen las zonas horarias. Es posible que no haya una hora a las 6 p.m. en una fecha en particular. La solución a este enigma depende de su contexto comercial y de sus reglas comerciales. Puede ignorar el enigma y quedarse literalmente preguntando si la hora actual está entre la hora de inicio y finalización objetivo. O puede aplicar la zona horaria a sus horas de inicio y finalización del día y dejar ZonedDateTime clase haga los ajustes que considere oportunos. Veamos ambos enfoques.

Ignorar anomalías

Primero, ignore cualquier anomalía. Pregunte de manera simple y literal si la hora actual del día se encuentra entre las horas objetivo de inicio y finalización.

Podemos extraer un objeto de hora del día del objeto de fecha y hora dividido en zonas.

LocalTime localTimeNow = zdt.toLocalTime(); // Extract a time-of-day from the zoned date-time object.

Compare eso con nuestras horas de inicio y parada. Tenga en cuenta que usamos aquí el enfoque semiabierto para definir un lapso de tiempo. En este enfoque, el comienzo es inclusivo mientras el final es exclusivo. Este enfoque es común en el trabajo de fecha y hora y, en general, es el camino más inteligente a seguir.

Boolean isNowOnOrAfterStart = ( ! localTimeNow.isBefore( start ) ) ;  // A briefer way of asking "is equal to OR is after" is "is not before". 
Boolean isNowBeforeStop = localTimeNow.isBefore( stop );
Boolean isNowInTargetZone = ( isNowOnOrAfterStart && isNowBeforeStop ); // Half-Open: beginning is inclusive while ending is exclusive.

Considere las anomalías

A continuación, consideramos las anomalías. Aplicamos las horas del día de inicio y finalización a la fecha actual dentro de la misma zona horaria. Extraemos solo la fecha del objeto de fecha y hora zonificado.

LocalDate localDateToday = zdt.toLocalDate();
ZonedDateTime zdtStart = ZonedDateTime.of( localDateToday , start , z );
ZonedDateTime zdtStop = ZonedDateTime.of( localDateToday , stop , z );

Estudie la documentación de la clase para comprender el comportamiento de ZonedDateTime.of en la resolución de valores de hora del día no válidos. No existe una forma perfecta de resolver valores de hora del día inexistentes, por lo que debe decidir si la forma de esta clase cumple con las reglas de su negocio.

ZonedDateTime.of

public static ZonedDateTime of(LocalDate date,
LocalTime time,
ZoneId zone)

Obtiene una instancia de ZonedDateTime de una fecha y hora local. Esto crea una fecha-hora dividida en zonas que coincide con la fecha y hora local de entrada lo más fielmente posible. Las reglas de zona horaria, como el horario de verano, significan que no todas las fechas y horas locales son válidas para la zona especificada, por lo que la fecha y hora local puede ajustarse.

La fecha y hora local y la primera se combinaron para formar una fecha y hora local. La fecha y hora local se resuelve luego en un solo instante en la línea de tiempo. Esto se logra al encontrar un desplazamiento válido de UTC / Greenwich para la fecha y hora local según lo definido por las reglas del ID de zona.

En la mayoría de los casos, solo hay un desplazamiento válido para una fecha y hora local. En el caso de una superposición, cuando los relojes se retrasan, hay dos compensaciones válidas. Este método utiliza el desplazamiento anterior que normalmente corresponde a “verano”.

En el caso de una brecha, cuando los relojes avanzan, no hay compensación válida. En cambio, la fecha y hora local se ajusta para que sea posterior según la longitud del espacio. Para un cambio típico de horario de verano de una hora, la fecha y hora local se moverá una hora más tarde al desplazamiento que normalmente corresponde a “verano”.

Aplique la misma lógica de comparación que vimos anteriormente.

Boolean isNowOnOrAfterStart = ( ! zdt.isBefore( zdtStart ) ) ;  // A briefer way of asking "is equal to OR is after" is "is not before". 
Boolean isNowBeforeStop = zdt.isBefore( zdtStop );
Boolean isNowInTargetZone = ( isNowOnOrAfterStart && isNowBeforeStop ); // Half-Open: beginning is inclusive while ending is exclusive.

Una forma alternativa de hacer la comparación es utilizar el práctico Interval clase del proyecto ThreeTen-Extra. Esa clase toma un dolor de Instant objetos, que puede extraer de su ZonedDateTime objetos. los Instant La clase representa un momento en la línea de tiempo en UTC con una resolución de nanosegundos (hasta nueve (9) dígitos de una fracción decimal).

Interval interval = Interval.of( zdtStart.toInstant() , zdtStop.toInstant() );
Boolean isNowInTargetZone = interval.contains( zdt.toInstant() );

Acerca de java.time

El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases suplantan las antiguas y problemáticas clases de fecha y hora heredadas, como java.util.Date, CalendarY 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.

¿Dónde obtener las clases java.time?

  • Java SE 8 y SE 9 y después
    • Incorporado.
    • 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 SE 7
    • Gran parte de la funcionalidad de java.time está retroportada a Java 6 y 7 en ThreeTen-Backport.
  • Androide
    • los ThreeTenABP el proyecto se adapta ThreeTen-Backport (mencionado anteriormente) para Android específicamente.
    • Ver Cómo usar ThreeTenABP….

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 más.

Aquí puedes ver las comentarios y valoraciones de los lectores

Puedes ayudar nuestra investigación exponiendo un comentario o valorándolo te damos la bienvenida.

¡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 *