Reputation: 15
I'm trying to filter list by a date format field.
class Timesheet {
String orderNumber
String groupCode
String periodCode
BigDecimal totalHours
Date importTime
Date generationTime // here
String description
And the controller:
def list = {
flash.periodCode = params.periodCode
flash.groupCode = params.groupCode
flash.orderNumber = params.orderNumber
// here
flash.generationTime = Date.parse('yyyy-mm-dd hh-mm-ss', params.generationTime)
if(!params.max) {
params.max = 20
}
def query
def criteria = Timesheet.createCriteria()
def results
query = {
and{
like("periodCode", '%' + params.periodCode + '%')
like("groupCode", '%' + params.groupCode + '%')
like("orderNumber", '%' + params.orderNumber + '%')
like("generationTime", '%' + params.generationTime + '%')
}
}
results = criteria.list(params, query)
render(view:'index', model:[ timesheetInstanceList: results ])
}
The date looks like: 2014-01-02 08:46:14 CET
.
The things that i'm trying to do is to put a text in a text field like "2014", and grails controller should find all records with date including "2014". Is there any simple way to do this ? The exception which i received is:
Unparseable date: "2013-12-31 08:02:55"
or
"java.lang.String cannot be cast to java.util.Date filtering grails"
Upvotes: 1
Views: 1449
Reputation: 3080
So the simplest way to do it is to get all timesheets that were created between 1st of january of that year and the 31st of December of the same year.
First you get two instances of Dates on for 01/01/$year and the second for 31/12/$year
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.WEEK_OF_YEAR, 1);
cal.set(Calendar.DAY_OF_WEEK, 1);
Date start = cal.getTime();
//set date to last day of $year
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, 11); // 11 = december
cal.set(Calendar.DAY_OF_MONTH, 31); // new years eve
Date end = cal.getTime();
Then all you need to do is to query the dates that are between start and end
query = {
and{
like("periodCode", '%' + params.periodCode + '%')
like("groupCode", '%' + params.groupCode + '%')
like("orderNumber", '%' + params.orderNumber + '%')
like("generationTime", '%' + params.generationTime + '%')
between('generationTime', start, end)
}
}
One thing that you should care about here is to shift the hours and minutes and seconds to 23:59:59
Upvotes: 0
Reputation: 2249
One option is to use a Derived Property to create a non-persisted generationYear
field using a SQL expression. Since this expression is raw SQL, the syntax will depend on your particular database but will follow this basic structure:
class Timesheet {
//...
Integer generationYear
static mapping = {
//...
generationYear formula: 'YEAR(generation_time)'
}
You will then be able to query directly on year:
eq("generationYear", flash.generationTime[Calendar.YEAR])
Upvotes: 3