Reputation: 1153
Lets say, i have a "Book" class with field "availableOn"(as shown below).
class Book {
String availableOn;
}
The fields holds values
How can i get all Books that are available within next two days? The below code would throw an exception ("java.util.Date cannot be cast to java.lang.String")
def books = c.list(){
between('availableOn', new Date(), new Date() + 2)
}
PS : Am working on a legacy DB, and so am not suppose to change the schema :(
Upvotes: 0
Views: 6069
Reputation: 50275
You can use format
on a date to get desired string format of it.
new Date().format('dd/MM/yyyy')
And your criteria would get modified to
def books = c.list(){
def todayDateStr = new Date().format('dd/MM/yyyy')
def twoDaysAfterTodayDateStr = (new Date()+2).format('dd/MM/yyyy')
or{
between('availableOn', todayDateStr, twoDaysAfterTodayDateStr)
eq 'availableOn', 'All Days'
}
}
Test if the str comparison works, otherwise other ways has to be used. Sending from phone, excuse my typos.
UPDATE
The above would fail in peculiar cases when dates are like "01/01/2013" and "07/11/2011".
Alternatively, you can use sqlRestriction
but in that case it gets tightly coupled with the underlying database. Something like this can be done if Oracle db is used:
def books = c.list(){
def todayDateStr = new Date().format('dd/MM/yyyy')
def twoDaysAfterTodayDateStr = (new Date()+2).format('dd/MM/yyyy')
or{
sqlRestriction "to_date(available_on, 'DD/MM/YYYY') between to_date(todayDateStr, 'DD/MM/YYYY') and to_date(twoDaysAfterTodayDateStr, 'DD/MM/YYYY')"
eq 'availableOn', 'All Days'
}
}
Upvotes: 0
Reputation: 9162
I don't have a criteria based solution, but you can try something like this:
Book.executeQuery(
"select book from Book book where book.availableOn = :availableOn or to_date(book.availableOn, :format) between (:startDate, :endDate) ",
[availableOn:"All days", format: "dd/MM/yyyy", startDate: startDate, endDate:endDate])
The problem with my solution is that this query becomes DB dependent. to_date
is an Oracle function. You may want to alter this to fit your database
Upvotes: 0
Reputation: 11327
I think there are 2 problems which the between
statement will have:
availableOn
cannot be converted to a Date
for comparison when its value is All days
availableOn
has a date value in it, it is not converted to a Date
for the comparisonI'd try something along the lines of this:
def now = new Date()
def books = Book.findAllByAvailableNotEqual("All days").findAll { book ->
Date.parse('dd/MM/yyyy', book.availableOn) > now && Date.parse('dd/MM/yyyy', book.availableOn) < now+2
}
Clearly, this can be done in a nicer way (adding some methods to the domain class for example), but this should illustrate my idea...
Upvotes: 1