Enlazando una fecha de Grails de params en un controlador

¿Por qué es tan difícil extraer la fecha de la vista a través de los parámetros en un controlador Grails?

No quiero extraer la fecha a mano de esta manera:

instance.dateX = parseDate(params["dateX_value"])//parseDate is from my helper class 

Solo quiero usar instance.properties = params .

En el modelo, el tipo es java.util.Date y en los parámetros está toda la información: [dateX_month: 'value', dateX_day: 'value', ...]

Busqué en la red y no encontré nada sobre esto. Esperé que Grails 1.3.0 pudiera ayudar, pero sigue siendo lo mismo.

¡No puedo y no creeré que sea necesario extraer la fecha a mano!

Versión de Grails> = 2.3

Una configuración en Config.groovy define los formatos de fecha que se usarán en toda la aplicación cuando se vinculan params a una Date

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

Los formatos especificados en grails.databinding.dateFormats se intentarán en el orden en que se incluyen en la lista.

Puede anular estos formatos de aplicación para un objeto de comando individual utilizando @BindingFormat

 import org.grails.databinding.BindingFormat class Person { @BindingFormat('MMddyyyy') Date birthDate } 

Versión de Grails <2.3

¡No puedo creer que la extracción de la fecha a mano sea imprescindible!

Tu terquedad es recompensada, ha sido posible vincular una fecha directamente desde mucho antes de Grails 1.3. Los pasos son:

(1) Cree una clase que registre un editor para su formato de fecha

 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) Haga que Grails sepa de este editor de fecha registrando el siguiente bean en grails-app/conf/spring/resources.groovy

 beans = { customPropertyEditorRegistrar(CustomDateEditorRegistrar) } 

(3) Ahora cuando envíe una fecha en un parámetro llamado foo en el formato yyyy/MM/dd , se vinculará automáticamente a una propiedad llamada foo utilizando:

 myDomainObject.properties = params 

o

 new MyDomainClass(params) 

Grails 2.1.1 tiene un nuevo método en params para un análisis seguro y nulo.

 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') 

Encuéntralo en el documento aquí

Versión de Grails> = 3.x

Puede establecer en application.yml los formatos de fecha que siguen a esta 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" 

¿Has intentado utilizar alguno de los plugins del datepicker de Grails?

He tenido buenas experiencias con el plugin de calendario .

(Cuando se utiliza el plugin de calendario) Cuando envía la solicitud de la selección de fecha, puede vincular automáticamente el parámetro de consulta al objeto de dominio que desea llenar con la solicitud.

P.ej

 new DomainObject(params) 

También puede analizar una cadena de fecha “aaaa / MM / dd” como …

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

@Don Gracias por la respuesta anterior.

Aquí hay una alternativa al editor personalizado que verifica el formato de la fecha y la fecha.

Groovy, solo agrega los semi colones en java

 import java.text.DateFormat import java.text.ParseException import org.springframework.util.StringUtils import java.beans.PropertyEditorSupport class CustomDateTimeEditor extends PropertyEditorSupport { private final java.text.DateFormat dateTimeFormat private final java.text.DateFormat dateFormat private final boolean allowEmpty public CustomDateTimeEditor(DateFormat dateTimeFormat, DateFormat dateFormat, boolean allowEmpty) { this.dateTimeFormat = dateTimeFormat this.dateFormat = dateFormat this.allowEmpty = allowEmpty } /** * Parse the Date from the given text, using the specified DateFormat. */ public void setAsText(String text) throws IllegalArgumentException { if (this.allowEmpty && !StringUtils.hasText(text)) { // Treat empty String as null value. setValue(null) } else { try { setValue(this.dateTimeFormat.parse(text)) } catch (ParseException dtex) { try { setValue(this.dateFormat.parse(text)) } catch ( ParseException dex ) { throw new IllegalArgumentException ("Could not parse date: " + dex.getMessage() + " " + dtex.getMessage() ) } } } } /** * Format the Date as String, using the specified DateFormat. */ public String getAsText() { Date value = (Date) getValue() return (value != null ? this.dateFormat.format(value) : "") } } 

Versión de Grails> = 2.3

Una versión de localeAware para convertir cadenas a la fecha

En src / groovy:

 package test import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest import org.grails.databinding.converters.ValueConverter import org.springframework.context.MessageSource import org.springframework.web.servlet.LocaleResolver import javax.servlet.http.HttpServletRequest import java.text.SimpleDateFormat class StringToDateConverter implements ValueConverter { MessageSource messageSource LocaleResolver localeResolver @Override boolean canConvert(Object value) { return value instanceof String } @Override Object convert(Object value) { String format = messageSource.getMessage('default.date.format', null, "dd/MM/yyyy", getLocale()) SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format) return simpleDateFormat.parse(value) } @Override Class< ?> getTargetType() { return Date.class } protected Locale getLocale() { def locale def request = GrailsWebRequest.lookup()?.currentRequest if(request instanceof HttpServletRequest) { locale = localeResolver?.resolveLocale(request) } if(locale == null) { locale = Locale.default } return locale } } 

En conf / spring / resources.groovy:

 beans = { defaultDateConverter(StringToDateConverter){ messageSource = ref('messageSource') localeResolver = ref('localeResolver') } } 

El nombre del bean ‘defaultDateConverter’ es realmente importante (para anular el convertidor de fecha predeterminado)