Search code examples
javaspring-mvcinputtimepickerspring-form

How to reliably accept time input in a Spring form?


I have an @Entity with a few java.util.Date fields; two of those should be time formatted. I need a way to accept time, preferably with a picker, for persisting to my db.

I've tried to use, for example,

@DateTimeFormat(pattern="hh:mm a")
private Date startTime;

along with this, and various attempts at adding type="time" and so forth,

...
<label for="startTime" class="sr-only">Start</label>
<form:input path="startTime" name="startTime" placeholder="Start" /
...

...but I'm getting Bad Request errors.

I know what that means, I just need to know a reliable way to fix it. How can I reliably accept time input in a Spring form?


Additional Network info:

Remote Address:[::1]:8080
Request URL:http://localhost:8080/shift_create/1.html
Request Method:POST
Status Code:400 Bad Request
Response Headers
view source
Cache-Control:must-revalidate,no-cache,no-store
Content-Length:307
Content-Type:text/html; charset=ISO-8859-1
Date:Mon, 10 Aug 2015 08:37:27 GMT
Server:Jetty(9.2.8.v20150217)
Request Headers
view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:58
Content-Type:application/x-www-form-urlencoded
Cookie:JSESSIONID=1w0rkel0w4eha96edvwq7rz1m
Host:localhost:8080
Origin:http://localhost:8080
Referer:http://localhost:8080/profile.html
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36
Form Data
view source
view URL encoded
name:ThisOne
shiftDate:08/13/2015
startTime:10:10 PM

Form data source : name=ThisOne&shiftDate=08%2F13%2F2015&startTime=10%3A10+PM

Solution

  • The way to get the time accepted turns out to be

    1. Create a DTO class for the entity which needs to store time
    2. Switch the type for the fields to String
    3. Include a time picker for input (I used ClockPicker)
    4. Provide methods which parse the time strings according to your timepicker and return a Date
    5. On POST use the methods from (4) to transfer the data from the DTO into the entity to be saved to the database

    Most of the code is trivial; the parsing part might look like this:

    // Time from a ClockPicker is "hh:mm"
    private Date getTime(String time) {
    
        if (time != null)
            return makeCalendar(getTimeComponents(getTimeComponents(time))).getTime();
        return null;
    }
    
    private String[] getTimeComponents(String time) {
        return time.split(":");
    }
    
    private int[] getTimeComponents(String... time) {
        int hour = Integer.parseInt(time[0]);
        return new int[] { 
                hour, 
                Integer.parseInt(time[1]), 
                0, 
                hour >= PM ? Calendar.AM : Calendar.PM 
        };
    }