Grails - illegal arguments for java.sql.Date - grails

I'm trying to create an sql.Date by creating a Calendar object on the current date. This is driving me crazy, if i hardcode the date as a string every thing is fine:
def dat = java.sql.Date.valueOf("2011-01-31");
But, if I create the same string in code I'm getting an illegal argument error.
def currentDay = {
def today = Calendar.getInstance();
def dateYear = today.get(Calendar.YEAR);
def dateMonth = today.get(Calendar.MONTH) + 1;
def dateDay =today.get(Calendar.DATE);
def todayDate = (dateYear + "-" + dateMonth + "-" + dateDay);
def todayDateString = todayDate.toString();
def todayDate2 = java.sql.Date.valueOf(todayDateString);
[ today : todayDate2 ]
}
Running this is yielding this stacktrace:
java.lang.IllegalArgumentException
at java.sql.Date.valueOf(Date.java:138)
at java_sql_Date$valueOf.call(Unknown Source)
at samma.TapesController$_closure7.doCall(TapesController.groovy:178)
at samma.TapesController$_closure7.doCall(TapesController.groovy)
at java.lang.Thread.run(Thread.java:619)
I know I'm doing something completely stupid, but I cannot figure out what, nor what a workaround could be.
Thanks
Donald.

Replace all the code above with
def currentDay = {
def todayDate = new java.sql.Date(new Date().time)
todayDate.clearTime()
[today: todayDate]
}

Why are you converting to a string at all? Just make sure your Calendar has the field values that you want, and then call
new java.sql.Date(calendar.getTime().getTime());
Alternatively, given that you just need the millis to be right, I would try to use Joda Time if at all possible - it'll be easier than manipulating a calendar, IMO. You can convert from a Joda Time instant (or whatever) to a long value very easily.

java.sql.Date.valueOf(String date) throws an IllegalArgumentException if the date given is not in the JDBC date escape format (yyyy-mm-dd). The date you are providing has the format yyyy-m-dd, (only one digit month for 1-9) therefore it is invalid.
As a workaround, use SimpleDateFormat to get a two digit month or directly work with dates without intermediate String conversion like Jon Skeet suggests.

Related

Check what Date Format user uses

How can I check within my Rails app what datetime format the user currently uses as his default?
I have this method:
def local_date(date, am_pm = false)
unless am_pm
date&.localtime&.strftime('(%d.%m.%Y, %H:%M)')
else
date&.localtime&.strftime('(%d.%m.%Y, %I:%M %p)')
end
end
I need to set am_pm accordingly to users local machines datetime format WITHOUT relying on the :locale parameter as not everyone who speaks english uses am/pm
This is achievable in Rails only with the help of a bit of client side JavaScript code. The client side code would detect whether the user is using 24 hours time format or 12 hours time format, and then store that information of a cookie.
Your server side code should then read that information from the cookie and set your time format accordingly.
Add this to your app/assets/javascript/application.js file.
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
var date = new Date(Date.UTC(2012, 11, 12, 3, 0, 0));
var dateString = date.toLocaleTimeString();
//apparently toLocaleTimeString() has a bug in Chrome. toString() however returns 12/24 hour formats. If one of two contains AM/PM execute 12 hour coding.
if (dateString.match(/am|pm/i) || date.toString().match(/am|pm/i) )
{
//12 hour clock
//check if we are already rendering in 12 hours format
if(getCookie("time_format") != "twelve")
{
document.cookie = "time_format=twelve";
/***
Now force the browser to reload current page from server.
Since we had set the the cookie, the server will now render
all pages in 12 hours format
****/
location.reload(true).
}
}
else
{
//24 hour clock
document.cookie = "time_format=twenty_four";
}
In your ApplicationController
class SomeController < ApplicationController
around_faction :set_time_format
def set_time_format
if cookie[:time_format]=="twelve"
#Set your desired time format string with 12 hour style
else
#default
#Set your desired time format string with 24 hour style
end
end
end

Subtract date in grails filter (le) in filter grails gorm [duplicate]

Is there a way in Groovy to get the duration between two Date objects? The duration format I'm looking for would be something like: 2 days, 10 hours, 30 minutes...
Thanks
TimeCategory has some methods for getting a duration. You could use it like
use(groovy.time.TimeCategory) {
def duration = date1 - date2
print "Days: ${duration.days}, Hours: ${duration.hours}, etc."
}
The use()-Syntax is weird to me.
so I prefer it like this:
def duration = groovy.time.TimeCategory.minus(
new Date(),
new Date(session.creationTime)
);
def values = [
"seconds: " + duration.seconds,
"min: " + duration.minutes,
"hours: " + duration.hours,
"days: " + duration.days,
"ago: " + duration.ago,
];

Unable to pass URL params into api request

I'm working with the Bing API and when I am making a SOAP request to acquire my campaign stats I'm having trouble passing URL params for date (provided by bootstrap datepicker) to the request.
I keep receiving the following error -
(a:DeserializationFailed) The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter https://adcenter.microsoft.com/v8:ReportRequest. The InnerException message was 'There was an error deserializing the object of type Microsoft.AdCenter.Advertiser.Reporting.Api.DataContracts.Request.ReportRequest. The value '' cannot be parsed as the type 'Int32'.'. Please see InnerException for more details.
It seems to me as though it is not able to receive the values I have set as the start/end date in the params. It is working when the params[:start]/[:end] values are nil
Here is the controller code setting up the date params (datepicker works fine for all other requests):
#Start Bing Reporting Code - set date for request ID
if params[:start].nil?
bing_start_date = DateTime.parse((Date.today - 7).to_s).strftime("%Y-%m-%d")
yearstart = bing_start_date[0,4]
monthstart = bing_start_date[5..6]
daystart = bing_start_date[8..9]
bing_end_date = DateTime.parse((Date.today - 1).to_s).strftime("%Y-%m-%d")
yearend = bing_end_date[0,4]
monthend = bing_end_date[5..6]
dayend = bing_end_date[8..9]
else
bing_start_date = params[:start]
yearstart = bing_start_date[2,4]
monthstart = bing_start_date[5..6]
daystart = bing_start_date[8..9]
bing_end_date = params[:end]
yearend = bing_end_date[2,4]
monthend = bing_end_date[5..6]
dayend = bing_end_date[8..9]
end
Here is the SOAP request body where I set the custom date range (using Savon gem):
soap.body = "<CustomDateRangeEnd i:nil=\"false\"><Day>#{dayend}</Day><Month>#{monthend}</Month><Year>#{yearend}</Year></CustomDateRangeEnd><CustomDateRangeStart i:nil=\"false\"><Day>#{daystart}</Day><Month>#{monthstart}</Month><Year>#{yearstart}</Year></CustomDateRangeStart></Time></ReportRequest>"
It works fine If I just set the yearend/start, monthend/start, dayend/start variables manually like so:
yearstart = '2014'
monthstart = '01'
daystart = '01'
#this would set the start date properly to Jan 1 2014
Foolish mistake. I used the same start index/length and ranges for the 'if' statement as I did for the 'else'. As a result it was throwing and empty string to <day>
The date output for the 'if' was "2014-01-13" and the output for the else was "20140113"
Therefore, I needed to adjust the index/length and ranges like so:
bing_start_date = params[:start]
yearstart = bing_start_date[0,4]
monthstart = bing_start_date[4..5]
daystart = bing_start_date[6..7]

Timestamp pattern

Let's assume I have the following reminder timestamp
local reminder_timestamp = "2013-12-13T00:00:00+01:00"
And I'm using the below function to return time in UTC
local function makeTimeStamp(dateString)
local pattern = "(%d+)%-(%d+)%-(%d+)%a(%d+)%:(%d+)%:([%d%.]+)([Z%p])(%d%d)%:?(%d%d)"
local year, month, day, hour, minute, seconds, tzoffset, offsethour, offsetmin = dateString:match(pattern)
local timestamp = os.time( {year=year, month=month, day=day, hour=hour, min=minute, sec=seconds} )
local offset = 0
if ( tzoffset ) then
if ( tzoffset == "+" or tzoffset == "-" ) then -- we have a timezone!
offset = offsethour * 60 + offsetmin
if ( tzoffset == "-" ) then
offset = offset * -1
end
timestamp = timestamp + offset
end
end
return timestamp
end
What should be the pattern above to match the reminder timestamp I mentioned earlier?
You need to use Lua's string parsing capabilities. Try a few of the techniques mentioned in the following, and if you still have issues, post specifically what is not working:
Question about splitting string and saving in several variables
Question about extracting data from a string, very similar to yours (although problem domain is GPS coordinates instead of date/time)
Question about how to do pattern matching in Lua, several good examples and links to docs
Here is the answer and the function actually works fine
pattern = "(%d+)%-(%d+)%-(%d+)%a(%d+)%:(%d+)%:([%d%.]+)([Z%p])(%d%d)%:?(%d%d)"
reminder_timestamp = "2013-12-23T08:00:00+01:00"
local year, month, day, hour, minute, seconds, tzoffset, offsethour, offsetmin = reminder_timestamp:match(pattern)
Resource: http://www.lua.org/manual/5.1/manual.html#5.4.1

Set default joda time duration/period format in Grails

When using joda time with Grails you can set the default LocalDate format as they have done here. I want to do the same thing with Duration and Period so I don't have to type something like
durationFormatter.print(exampleObject.myDuration)
every time I want to display a duration or period. I want a call to the toString() method of a Duration / Period object and have it print in the desired format.
I have tried to implement PeriodFormatter in my config file much like they did here, but to no avail. Here is what I have so far in my config file:
jodatime {
format.org.joda.time.LocalDate = "yyyy-MM-dd"
format.org.joda.time.PeriodFormatter = { new format.org.joda.time.PeriodFormatterBuilder()
.appendMonths()
.appendSuffix( " month", " months" )
.appendWeeks()
.appendSuffix( " week", " weeks" )
.appendDays()
.appendSuffix( " day", " days" )
.appendHours()
.appendSuffix( " hour", " hours" )
.toFormatter();
}
}
class
ISOPeriodFormat
field
cStandard
this is default period formatter. This field is private static and haven't setter. But you can change this value using java-reflection API
final Field f = ISOPeriodFormat.class.getDeclaredField("cStandard");
f.setAccessible(true);
f.set(null, yourPeriodFormatter);

Resources