I have a table with a range of hours and minutes, "07:00" till "14:00" and a Java Api that gets these values. At first I was using seconds (28800 to 50400).
I want to get all the values in between for every 5 minutes ("07:05", "07:10", "07:15", "07:20"... "08:15"... "13:55", "14:00").
But I cant quite figure how to do this in a clean way.
Class method (on console works great but the output of the api is in nano seconds:
@Transient
public List<LocalTime> getHorarios(){
long initialCapacity = 0;
List<LocalTime> times = new ArrayList<LocalTime> ( ( int ) initialCapacity );
while ( ! nextTime.isAfter ( stop ) ) {
times.add ( nextTime );
nextTime = nextTime.plusMinutes ( 5 );
}
return times;
}
@Transient
public List<LocalTime> getHorariosLibres(List<LocalTime> horariosTomados){
List<LocalTime> horariosLibres = getHorarios();
horariosLibres.removeAll(horariosTomados);
return horariosLibres;
}
So far this is my controller:
@RequestMapping(value = "/horario/{fecha}", method = RequestMethod.GET)
@ResponseBody
public Object queryHorariosLibres(@PathVariable("fecha") @DateTimeFormat(pattern="yyyy-MM-dd") Date fecha) {
List<LocalTime> horariosTomados = turnoService.getHorariosTomados(fecha);
Calendar dia = new GregorianCalendar();
dia.setTime(fecha);
Horario horario = horarioRepository.findByDia(dia.get(Calendar.DAY_OF_WEEK));
List<LocalTime> horariosLibres = horario.getHorariosLibres(horariosTomados);
return horariosLibres;
}
Actual output through API:
[{"hour":7,"minute":0,"second":0,"nano":0},{"hour":7,"minute":5,"second":0,"nano":0},{"hour":7,"minute":10,"second":0,"nano":0},{"hour":7,"minute":15,"second":0,"nano":0},{"hour":7,"minute":20,"second":0,"nano":0},{"hour":7,"minute":25,"second":0,"nano":0},{"hour":7,"minute":30,"second":0,"nano":0},{"hour":7,"minute":35,"second":0,"nano":0},{"hour":7,"minute":40,"second":0,"nano":0},{"hour":7,"minute":45,"second":0,"nano":0},{"hour":7,"minute":50,"second":0,"nano":0},{"hour":7,"minute":55,"second":0,"nano":0},{"hour":8,"minute":0,"second":0,"nano":0},{"hour":8,"minute":5,"second":0,"nano":0},{"hour":8,"minute":10,"second":0,"nano":0},{"hour":8,"minute":15,"second":0,"nano":0},{"hour":8,"minute":20,"second":0,"nano":0},{"hour":8,"minute":25,"second":0,"nano":0},{"hour":8,"minute":30,"second":0,"nano":0},{"hour":8,"minute":35,"second":0,"nano":0},{"hour":8,"minute":40,"second":0,"nano":0},{"hour":8,"minute":45,"second":0,"nano":0},{"hour":8,"minute":50,"second":0,"nano":0},{"hour":8,"minute":55,"second":0,"nano":0},{"hour":9,"minute":0,"second":0,"nano":0},{"hour":9,"minute":5,"second":0,"nano":0},{"hour":9,"minute":10,"second":0,"nano":0},{"hour":9,"minute":15,"second":0,"nano":0},{"hour":9,"minute":20,"second":0,"nano":0},{"hour":9,"minute":25,"second":0,"nano":0},{"hour":9,"minute":30,"second":0,"nano":0},{"hour":9,"minute":35,"second":0,"nano":0},{"hour":9,"minute":40,"second":0,"nano":0},{"hour":9,"minute":45,"second":0,"nano":0},{"hour":9,"minute":50,"second":0,"nano":0},{"hour":9,"minute":55,"second":0,"nano":0},{"hour":10,"minute":0,"second":0,"nano":0},{"hour":10,"minute":5,"second":0,"nano":0},{"hour":10,"minute":10,"second":0,"nano":0},{"hour":10,"minute":15,"second":0,"nano":0},{"hour":10,"minute":20,"second":0,"nano":0},{"hour":10,"minute":25,"second":0,"nano":0},{"hour":10,"minute":30,"second":0,"nano":0},{"hour":10,"minute":35,"second":0,"nano":0},{"hour":10,"minute":40,"second":0,"nano":0},{"hour":10,"minute":45,"second":0,"nano":0},{"hour":10,"minute":50,"second":0,"nano":0},{"hour":10,"minute":55,"second":0,"nano":0},{"hour":11,"minute":0,"second":0,"nano":0},{"hour":11,"minute":5,"second":0,"nano":0},{"hour":11,"minute":10,"second":0,"nano":0},{"hour":11,"minute":15,"second":0,"nano":0},{"hour":11,"minute":20,"second":0,"nano":0},{"hour":11,"minute":25,"second":0,"nano":0},{"hour":11,"minute":30,"second":0,"nano":0},{"hour":11,"minute":35,"second":0,"nano":0},{"hour":11,"minute":40,"second":0,"nano":0},{"hour":11,"minute":45,"second":0,"nano":0},{"hour":11,"minute":50,"second":0,"nano":0},{"hour":11,"minute":55,"second":0,"nano":0},{"hour":12,"minute":0,"second":0,"nano":0},{"hour":12,"minute":5,"second":0,"nano":0},{"hour":12,"minute":10,"second":0,"nano":0},{"hour":12,"minute":15,"second":0,"nano":0},{"hour":12,"minute":20,"second":0,"nano":0},{"hour":12,"minute":25,"second":0,"nano":0},{"hour":12,"minute":30,"second":0,"nano":0},{"hour":12,"minute":35,"second":0,"nano":0},{"hour":12,"minute":40,"second":0,"nano":0},{"hour":12,"minute":45,"second":0,"nano":0},{"hour":12,"minute":50,"second":0,"nano":0},{"hour":12,"minute":55,"second":0,"nano":0},{"hour":13,"minute":0,"second":0,"nano":0},{"hour":13,"minute":5,"second":0,"nano":0},{"hour":13,"minute":10,"second":0,"nano":0},{"hour":13,"minute":15,"second":0,"nano":0},{"hour":13,"minute":20,"second":0,"nano":0},{"hour":13,"minute":25,"second":0,"nano":0},{"hour":13,"minute":30,"second":0,"nano":0},{"hour":13,"minute":35,"second":0,"nano":0},{"hour":13,"minute":40,"second":0,"nano":0},{"hour":13,"minute":45,"second":0,"nano":0},{"hour":13,"minute":50,"second":0,"nano":0},{"hour":13,"minute":55,"second":0,"nano":0},{"hour":14,"minute":0,"second":0,"nano":0}]
No need to roll-your-own data type here.
java.time.LocalTime
Java 8 and later has a data type to fit this case: java.time.LocalTime
, a time without date and without time zone. Use this for your business logic. From these objects you can generate a String representation for display to the user.
java.sql.Time
JDBC has a data type for transferring such values in and out of your database: java.sql.Time
.
String inputStart = "07:00";
String inputStop = "14:00";
LocalTime start = LocalTime.parse ( inputStart );
LocalTime stop = LocalTime.parse ( inputStop );
LocalTime nextTime = start;
Duration duration = Duration.ofMinutes ( 5 );
long initialCapacity = ( Duration.between ( start , stop ).toMinutes () / duration.toMinutes () ) + 1; // Optional line of code. Could be omitted.
List<LocalTime> times = new ArrayList ( ( int ) initialCapacity );
while ( ! nextTime.isAfter ( stop ) ) {
times.add ( nextTime );
nextTime = nextTime.plus ( duration ); // Or call .plusMinutes( int ) and pass a number of minutes.
}
Dump to console.
System.out.println ( "times: " + times + " initialCapacity: " + initialCapacity + " times.size " + times.size () );
times: [07:00, 07:05, 07:10, 07:15, 07:20, 07:25, 07:30, 07:35, 07:40, 07:45, 07:50, 07:55, 08:00, 08:05, 08:10, 08:15, 08:20, 08:25, 08:30, 08:35, 08:40, 08:45, 08:50, 08:55, 09:00, 09:05, 09:10, 09:15, 09:20, 09:25, 09:30, 09:35, 09:40, 09:45, 09:50, 09:55, 10:00, 10:05, 10:10, 10:15, 10:20, 10:25, 10:30, 10:35, 10:40, 10:45, 10:50, 10:55, 11:00, 11:05, 11:10, 11:15, 11:20, 11:25, 11:30, 11:35, 11:40, 11:45, 11:50, 11:55, 12:00, 12:05, 12:10, 12:15, 12:20, 12:25, 12:30, 12:35, 12:40, 12:45, 12:50, 12:55, 13:00, 13:05, 13:10, 13:15, 13:20, 13:25, 13:30, 13:35, 13:40, 13:45, 13:50, 13:55, 14:00] initialCapacity: 85 times.size 85
For input into a database, convert to java.sql.Time
.
java.sql.Time sqlTime = java.sql.Time.valueOf( myLocalTime );
Important: Be aware that both your original code and this java.time code example are only using imaginary times-of-day that assume a fictitious 24-hour generic day. Anomalies such as Daylight Saving Time (DST) means that days are not always 24-hours long. Some of your listed times may not exist on a particular date in a particular time zone.
If you care about real moments, valid times on certain dates, use the java.time.ZonedDateTime
(or .OffsetDateTime
). For database transfer, use java.sql.Timestamp
.