Binding a Grails date from params in a controller

Solution 1:

Grails Version >= 2.3

A setting in Config.groovy defines the date formats which will be used application-wide when binding params to a Date

grails.databinding.dateFormats = [
        'MMddyyyy', 'yyyy-MM-dd HH:mm:ss.S', "yyyy-MM-dd'T'hh:mm:ss'Z'"
]

The formats specified in grails.databinding.dateFormats will be attempted in the order in which they are included in the List.

You can override these application-wide formats for an individual command object using @BindingFormat

import org.grails.databinding.BindingFormat

class Person { 
    @BindingFormat('MMddyyyy') 
    Date birthDate 
}

Grails Version < 2.3

i can't and will not belief that extracting the date by hand is nessesary!

Your stubbornness is rewarded, it has been possible to bind a date directly since long before Grails 1.3. The steps are:

(1) Create a class that registers an editor for your date format

import org.springframework.beans.PropertyEditorRegistrar
import org.springframework.beans.PropertyEditorRegistry
import org.springframework.beans.propertyeditors.CustomDateEditor
import java.text.SimpleDateFormat

public class CustomDateEditorRegistrar implements PropertyEditorRegistrar {

    public void registerCustomEditors(PropertyEditorRegistry registry) {

        String dateFormat = 'yyyy/MM/dd'
        registry.registerCustomEditor(Date, new CustomDateEditor(new SimpleDateFormat(dateFormat), true))
    }
}

(2) Make Grails aware of this date editor by registering the following bean in grails-app/conf/spring/resources.groovy

beans = {
    customPropertyEditorRegistrar(CustomDateEditorRegistrar)
}

(3) Now when you send a date in a parameter named foo in the format yyyy/MM/dd it will automatically be bound to a property named foo using either:

myDomainObject.properties = params

or

new MyDomainClass(params)

Solution 2:

Grails 2.1.1 has new method in params for easy null safe parsing.

def val = params.date('myDate', 'dd-MM-yyyy')
// or a list for formats
def val = params.date('myDate', ['yyyy-MM-dd', 'yyyyMMdd', 'yyMMdd']) 
// or the format read from messages.properties via the key 'date.myDate.format'
def val = params.date('myDate')

Find it in doc here

Solution 3:

Grails Version >= 3.x

You can set in application.yml the date formats following this syntax:

grails:
  databinding:
    dateFormats:
      - 'dd/MM/yyyy'
      - 'dd/MM/yyyy HH:mm:ss'
      - 'yyyy-MM-dd HH:mm:ss.S'
      - "yyyy-MM-dd'T'hh:mm:ss'Z'"
      - "yyyy-MM-dd HH:mm:ss.S z"
      - "yyyy-MM-dd'T'HH:mm:ssX"

Solution 4:

Have you tried using any of the Grails date picker plugins?

Ive had good experiences with the calendar plugin.

(When using the calendar plugin) When you submit the request of the date selection you can automatically bind the query parameter to the domain object you want to populate with the request.

E.g.

new DomainObject(params)

You can also parse a "yyyy/MM/dd" date string like so...

new Date().parse("yyyy/MM/dd", "2010/03/18")