Ashish Joseph
Ashish Joseph

Reputation: 1153

Grails - Convert String data to Date

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

Answers (3)

dmahapatro
dmahapatro

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

WeMakeSoftware
WeMakeSoftware

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

zoran119
zoran119

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
  • Even when availableOn has a date value in it, it is not converted to a Date for the comparison

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

Related Questions