Check if date is between two dates in the 30 min range

Asked

Viewed 2,791 times

2

I have a service that before saving some value in the bank, it is necessary to be checked if it is within some period already saved in the bank. Each period consists of half an hour. ex:

10:00
10:30
11:00

If the user tries to put 10:31, an exception must be triggered. My service is ready and all the logic implemented, but I wanted help to understand why is not entering the if when I send the same date 2 times or for ex 10:31.

@Service
public class CalendarService {

@Autowired
private CalendarRepository calendarRepository;

public Calendar create(Calendar calendar)
{
    calendar.setId(null);
    checkSlotBetweenDate(calendar);
    addThirtyMinutes(calendar);
    calendar.setName("Crane");

    return calendarRepository.save(calendar);
}

public void addThirtyMinutes(Calendar calendar)
{
    java.util.Calendar cal = java.util.Calendar.getInstance();
    cal.setTime(calendar.getStartTime());
    cal.add(java.util.Calendar.MINUTE, 30);
    calendar.setEndTime(cal.getTime());
}

public void checkSlotBetweenDate(Calendar calendar)
{
    Iterable<Calendar> cal = calendarRepository.findAll();

    for(Calendar key: cal)
    {
        System.out.println(calendar.getStartTime()+ " Enviado por mim ");
        System.out.println(convertTime(key.getStartTime())+ " Dt inicio e fim do Banco  " +convertTime(key.getEndTime()));
        if(convertTime(key.getStartTime()).after(calendar.getStartTime()) && convertTime(key.getEndTime()).before(calendar.getStartTime()))
        {
            throw new BadRequestException("O período selecionado já está ocupado!");
        }
    }
}

public Date convertTime(Date date) 
{    
    java.util.Calendar cal = java.util.Calendar.getInstance();  
    cal.setTime(date);
    return cal.getTime(); 
}
}   

I’ve tried several if's, but nothing fall into the exception. As for example:

if (key.getStartTime().getTime() >= calendar.getStartTime().getTime()
    && key.getEndTime().getTime() <= calendar.getStartTime().getTime())

On the console is printed:

Mon May 07 20:00:00 BRT 2018 Enviado por mim 
Mon May 07 20:00:00 BRT 2018 Dt inicio e fim do Banco  Mon May 07 20:30:00 BRT 2018

And in fact, it was supposed to be the exception because the dates are the same. I ask for help in this logic and if anyone has any other logic or suggestion, please tell me.

  • I did not quite understand the logic. If the periods are 10:00, 10:30 and 11:00, should only accept these times? (so 10:31 is not accepted?) And in your example, the times are 20:00 and 20:30, I’m not understanding what are the criteria to accept a value as valid or make an exception. Another detail is that method convertTime is not converting anything (compare the value of date.getTime() before and after the method and see that in fact it changes nothing - better, see that convertTime(date).equals(date) returns true, i.e., the method is returning another Date of the same value)

  • That 10:00, 10:30 and 11:00 was just one example. The rule would be like this, if I make a registration at 10:30, the system will add + 30 min and make this time unavailable for another registration. In other words, from 10:30 to 11:00 it is not possible to register + nd within this range, example would be 10:31. Without convertTime the date was in a +/- format like this: "2018-05-07T20:31:00" and there was an error in If, because of that I had to use this resource. You’ve come to understand the agr logic, my friend?

  • Picked up here, without the convertTime returns 2018-05-07 20:00.0.

1 answer

2


Based in his comment, you only need to take the date of registration, add 30 minutes and finally compare the date of the new registration with the interval obtained.

In this case, your method for adding 30 minutes is correct. I would only change the name of your class because it has 2 classes called Calendar can confuse a little (I myself took a long time to understand in your code that are 2 different classes).

Anyway, assuming you have 2 instances of java.util.Calendar, where the end is 30 minutes after the beginning, and another instance you want to check is within the interval, the comparison is like this:

// todas são java.util.Calendar
Calendar inicio = // data de inicio
Calendar fim = // 30 minutos depois do início

Calendar cal = // data que eu quero testar

if (cal.before(inicio) || cal.after(fim)) {
    // cal está fora do intervalo
} else {
    // cal está dentro do intervalo
}

In short, if the date in question is before the beginning, or after the end, then it is outside the range and therefore can be registered. Otherwise, you are within the range and cannot be registered.

If you are working with java.util.Date, she also possesses the methods after and before and the logic is the same.


Obs: your method convertTime makes a cal.setTime(date); for soon after return cal.getTime(), or is returning the same date it received (in practice, it is as if the method did not make any conversion, as it returns a Date of the same value as).

java time.

If it is possible to change your classes, I suggest using the API java.time, available from Java 8. If you use Java 6 or 7, you can use Threeten Backport, which has the same classes as java.time, the only difference is that in the backport the classes are in the package org.threeten.bp.

To know the exact moment something is done, you can use the class Instant. This API is much more user friendly and less confusing than Date and Calendar, and the code would look like this:

// data/hora atual
Instant inicio = Instant.now();
// 30 minutos depois
Instant fim = inicio.plus(30, ChronoUnit.MINUTES);

Instant instant = // data/hora que quero comparar

if (instant.isBefore(inicio) || instant.isAfter(fim)) {
    // fora do intervalo
} else {
    // dentro do intervalo
}

In case you need to work with Date, it is possible to convert easily. The only difference is that in Java 8 there are proper methods for this in the class Date:

// converter para java.util.Date
Date date = Date.from(instant);
// converter para java.time.Instant
Instant inst = date.toInstant();

While in Threeten Backport you must use the class org.threeten.bp.DateTimeUtils:

// converter para java.util.Date
Date date = DateTimeUtils.toDate(instant);
// converter para org.threeten.bp.Instant
Instant inst = DateTimeUtils.toInstant(date);
  • 1

    Actually I vacillated by calling the entity Calendar rs but d qq form, mt obgd by the answer. I organized the code and solved with this if(selectedDate.after(convertTime(start)) && selectedDate.before(convertTime(end)). I will mark as solved because besides your reply to be mt good, helped me to understand my mistake. The only thing that has been pending is that if I send 10:30 twice, it accepts and does not enter the if because the condition is IF AFTER 10:30. Sort if I order from 10:31 to 10:59 falls in if. If you have any tips, I will be grateful!

  • 1

    @Crane You can change the if (after 10:30) for if (!(before 10:30)) (if nay is before 10:30, ie if it is "after or equal to 10:30")

  • 1

    Perfect guy! Solved! Very obgd again. I found that after had the ! before msm effect. But the after equals only > and ! berofe to >=.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.