Vinculando uma data Grails de params em um controller

Por que é tão difícil extrair a data da visualização através dos parâmetros em um controlador grails?

Eu não quero extrair a data manualmente assim:

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

Eu só quero usar instance.properties = params .

No modelo, o tipo é java.util.Date e nos parâmetros está toda a informação: [dateX_month: 'value', dateX_day: 'value', ...]

Eu procurei na net e não encontrei nada sobre isso. Eu esperava que o Grails 1.3.0 pudesse ajudar, mas ainda a mesma coisa.

Eu não posso e não vou acreditar que extrair a data à mão é necessário!

Versão Grails> = 2.3

Uma configuração no Config.groovy define os formatos de data que serão usados ​​em toda a aplicação ao vincular parâmetros a uma Date

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

Os formatos especificados em grails.databinding.dateFormats serão tentados na ordem em que estão incluídos na Lista.

Você pode replace esses formatos de aplicativo @BindingFormat por um object de comando individual usando @BindingFormat

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

Versão Grails <2.3

Eu não posso e não acredito que extrair a data à mão é nessesary!

Sua teimosia é recompensada, tem sido possível vincular uma data diretamente desde muito antes de Grails 1.3. Os passos são:

(1) Crie uma class que registre um editor para o seu formato de data

 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) Faça Grails ciente deste editor de data registrando o seguinte bean em grails-app/conf/spring/resources.groovy

 beans = { customPropertyEditorRegistrar(CustomDateEditorRegistrar) } 

(3) Agora, quando você envia uma data em um parâmetro chamado foo no formato yyyy/MM/dd ela será automaticamente vinculada a uma propriedade chamada foo usando:

 myDomainObject.properties = params 

ou

 new MyDomainClass(params) 

O Grails 2.1.1 tem um novo método em params para facilitar a análise nula e segura.

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

Encontre no doc aqui

Versão Grails> = 3.x

Você pode definir no application.yml os formatos de data seguindo 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" 

Você já tentou usar algum dos plugins do selecionador de datas Grails?

Eu tive boas experiências com o plugin de calendar .

(Ao usar o plug-in de calendar) Ao enviar a solicitação da seleção de data, você pode vincular automaticamente o parâmetro de consulta ao object de domínio que deseja preencher com a solicitação.

Por exemplo

 new DomainObject(params) 

Você também pode analisar uma string de data “aaaa / MM / dd” como …

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

@Don Obrigado pela resposta acima.

Aqui está uma alternativa para o editor personalizado que verifica o primeiro dia e o formato de data.

Groovy, apenas adicione semi-colons de volta para 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) : "") } } 

Versão Grails> = 2.3

Uma versão localeAware para converter strings para data

Em 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 } } 

Em conf / spring / resources.groovy:

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

O nome do bean ‘defaultDateConverter’ é realmente importante (para replace o conversor de data padrão)