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

2

I have a service that before saving some value in the bank, it needs to be checked if it is within some time 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 logic implemented, but I wanted help to understand why it is not entering if when I send the same date 2 times or by 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 have tried several if 's, but nothing falls into the exception. For example:

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

In the console it 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 to fall into the exception because the dates are the same. I ask for help in this logic and if someone has another logic or suggestion, please tell me.

    
asked by anonymous 09.05.2018 / 21:27

1 answer

2

Based in your comment , you just need to get the date of the record, add 30 minutes and finally compare the date of the new record with the interval obtained.

In this case, your method for adding 30 minutes is correct. I would just change the name of your class, because having 2 classes named Calendar might confuse a bit (I even took time to understand in your code that there are 2 different classes).

Anyway, assuming you have 2 instances of java.util.Calendar , the end is 30 minutes after the start, and another instance you want to check if it is within the range, the comparison looks 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 out of range and therefore can be registered. Otherwise, it is within range and can not be registered.

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

Obs : your method convertTime makes a cal.setTime(date); so soon then returns cal.getTime() , ie it is returning the same date it received (in practice, it is as if the method did not do any conversion, because it returns a Date with the same value that it received).

java.time

If you can change your classes, I suggest using the java.time API, 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 org.threeten.bp package.

To know the exact moment something is done, you can use the Instant class. This API is much friendlier 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
}

If you need to work with Date , you can easily convert. The only difference is that in Java 8 there are methods suitable for this in class Date :

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

While in the ThreeTen Backport you should use the org.threeten.bp.DateTimeUtils class:

// converter para java.util.Date
Date date = DateTimeUtils.toDate(instant);
// converter para org.threeten.bp.Instant
Instant inst = DateTimeUtils.toInstant(date);
    
09.05.2018 / 23:22