Spring JDBCTemplate date format error on oracle query - java

I want to write a query which returns list of result data in between two dates(including them).This is what I tested and the query returns with an error ORA-01830: date format picture ends before converting entire input string.
DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date from=df.parse("2015-05-27 12:12:12");
Date toDate=df.parse("2015-05-28 12:12:12");
//this returns ORA-01830: date format picture ends before converting entire input string
sfaTemplate.query("select * from my_requests where received_from=? and to_date(request_at)>=to_date(?) and to_date(request_at)<=to_date(?) ", new BeanPropertyRowMapper<SFAReload>(SFAReload.class), 12, from, toDate);
//but this works just change to_date(request_at)<=to_date(?) into to_date(request_at)>=to_date(?)
sfaTemplate.query("select * from my_requests where received_from=? and to_date(request_at)>=to_date(?) and to_date(request_at)>=to_date(?) ", new BeanPropertyRowMapper<SFAReload>(SFAReload.class), 12, from, toDate);
changing the to_date(request_at) <= to_date(?) into to_date(request_at) >= to_date(?) makes query run.Can some one give me the reason?

you are using to_date(?) in your query but you are passing two date objects as parameters. to_date in oracle expects a string (and an optional format), so you must choose between
passing a Date object in jdbc template (as you are doing now) changing the query avoiding the to_date conversion and using for example to_date(request_at)<=to_date(?)
passing a String object (i.e. "2015-05-28 12:12:12")in jdbc template representing a date and using a to_date(?,'yyyy-mm-dd hh24:mi:ss') in the query.

Related

Insert date in oracle using prepared statemnt

My user interface returns a date as String (01/06/2016 2:30 am)to controller and I want to insert the into oracle 10 database by changing it from string to date and format to (dd-MMM-yy hh:mm:ss a) where the field is date type. Below is What I tried but getting Illegal Argument exception .
In controller I formatted to date and passed it to service layer through DTO
created : 01/06/2016 09:00 pm
SimpleDateFormat fromUser = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
SimpleDateFormat myFormat = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a");
String reformattedStr = myFormat.format(fromUser.parse(created));
System.out.println("reformattedStr is : " + reformattedStr);
**reformattedStr 06-Jan-16 09:00:00 PM
Date formateDate=myFormat.parse(reformattedStr);
In service through prepared statement i am trying to insert , the date and other fields.
stmt.setTimestamp (8,new java.sql.Timestamp(news.getCreated().getTime()));
Can anyone please suggest?
Thanks for the help , I have updated the code, it might help some one.
If the column data type is timestamp, you don't need to do explicit conversion for the date. The statement.setTimestamp() method takes care of it.
There are two ways to create TimeStamp instance from a java.util.Date object.
new TimeStamp(date.getTime())
or
TimeStamp.value(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date))
The value returned by the news.getCreated().toString() method might not be returning the correctly formatted date - if it's returning formatted date.
Please refer to the javadoc for TimeStamp class for more information.
Thanks

How to match system date with the date from database mysql

I have a database named work created using mysql in which a table named register is created. It contain a column renewdate. I accessed the table from java swing like this
conn=ConnectionDB.conn();
Date d=sysdate();
String sql="select renewdate from register";
try
{
ps=conn.prepareStatement(sql);
ResultSet rs=ps.executeQuery();
Date dates;
while(rs.next())
{
dates = rs.getDate("renewdate");
System.out.println(dates);
if(dates==d)
{
SendMailTLS.sendMail();
}
}
}
My problem is to send an email when renewdate equals system date. I generate current date using function sysdate() and assigned it to d. Also assigned renewdate in table to dates using dates = rs.getDate("renewdate").
My problem is I can not match up both d and dates and thus can not sent email. Could you help me how to match d and dates.
I tried while(rs.next()) all the dates from table register is obtained. But can not match with d using if(dates==d). Also I tried if(rs.next()), but it only fetch first renewdate from table. So how could i check all the values of renewdate and match with the current date to sent message
Just change a query string to
// NOW() in mysql will get the current date and time. So here you get only renewdates matched with current date and time
String sql="select renewdate from register where renewdate = NOW()";
// If you want to compare only with date not time, then go with
String sql="select renewdate from register where renewdate = CURDATE()";
There is no need for this if(dates == d) in your above code. Send mail as soon you have next element in your while condition.
Nice code! So:
Save the value of date into strings like:
Date d=sysdate();
String strDate1 = d.toString();
String strDate2 = rs.getDate("renewdate").toString;
Then compare it like:
strDate1.equals(strDate2);
as Strings contain references to "words", not the "words" themself, the == opereator would do something else;
Couly you please send us your whole code for this app anyway, as it would be a nice peace of work to learn from?
If you want to do it in code, here is a way:-
Convert date fetched from database into java.util.Date object using below code (assuming date is stored in GMT):
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
Date dateInDB = formatter.parse(dates);
Then, you can simply use java.util.Date equals method to compare d with dateInDB.
If you want to ignore time portion while comparing two dates, call below method (that sets time portion to 00:00:00) for each date and use returned date in equals method:
public static Date getZeroTimeDate(Date dateWithTime) {
Date res = dateWithTime;
Calendar calendar = Calendar.getInstance();
calendar.setTime( dateWithTime );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
res = calendar.getTime();
return res;
}
This way it does not uses any deprecated method too.
Hope this helps!

how to insert data type date(yyyy-MM-dd) in sqlite database and retrive data between two dates in android

I have a Sqlite3 database table contains name,address,date of birth details.i want to display 1990-01-01 to 1995-01-01 details.
but Sqlite3 database stores only following data types.
TEXT
NUMERIC
INTEGER
REAL
NONE
Any one have some hint to store and retrieve date format data..?
From my own experience on doing several projects with database in Android my answer is:
Do not store the date as a string. Never! Ever! Store them as Unix timestamps and format them as needed during runtime.
the important thing here is to separate what is your data and what is the on-screen representation of your data. Storing in a database the on-screen representation of your data is wrong.
You'll always store your dates as INTEGER types.
So for example to store the date now you'll store the value System.currentTimeInMilis
To select between 1990-01-01 and 1995-01-01 you will:
long val1 = new GregorianCalendar(1990, 01, 01).getTimeInMillis();
long val2 = new GregorianCalendar(1995, 01, 01).getTimeInMillis();
and then you'll do the normal SELECT statement between those 2 values.
to show those values in the screen as yyyy-MM-dd you'll use the SimpleDateFormat class:
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
long longDate = cursor.getLong(colNumber); // from the database
String stringDate = dateFormat.format(new Date(longDate));
Use this code to convert your date into millisecond format and store it into your database as INTEGER types
String someDate = "1995-01-01";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(someDate);
System.out.println(date.getTime());
date.getTime()-give the millisecond format
At the same way to convert your input (i.e from 1990-01-01 and to date 1995-01-01)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = sdf.parse(1990-01-01);
value1=date.getTime();
Date date2 = sdf.parse(1995-01-01);
value2=date.getTime();
Retrieve from database using following query
db.rawQuery("SELECT * FROM table_name WHERE column_name BETWEEN "+value1+" AND "+value2+"",null);
or
db.rawQuery("SELECT * FROM table_name WHERE column_name<="+value1+" AND column_name>="+value2+"",null);
You can do something like this
DateFormat df=new SimpleDateFormat("yyyy-MM-dd");
Date date1=df.parse("1990-01-01");
Date date2=df.parse("1995-01-01");
Date myDate=df.parse("1992-01-01"); // checking date
if((date1.getTime()<myDate.getTime())&&(myDate.getTime()<date2.getTime())){
System.out.println(df.format(myDate)+" is in this range");
}else{
System.out.println(df.format(myDate)+" is not in this range");
}
Since the format you want to use (yyyy-MM-dd) is ordered in the same way as a String (i.e. for any dates x and y you would choose, if x < y as a Date, then x < y as a String), you can simply store the dates as Strings (TEXT) in your database.
When selecting the values between them, you would just have to use a WHERE clause in your SELECT statement like this:
SELECT * FROM yourTable WHERE yourDateFieldName > ? and yourDateFieldName < ?
You can then use DateFormat.format to set the values for the ? parameters of your prepared statement. The first parameter would be the "start" date, and the second would be the "end" date. You can replace < with <= and > with >= if you want the items on start and end dates included.
This gives you a String representation of a Date. To convert from that to an actual Date object you can use date formatter's parse method (i.e. SimpleDateFormat.parse).
Another, "cleaner", approach would be to use the SQLite date and time functions (see here). While SQLite doesn't have a DATE type for storing date values, it has helper functions that you can use to interpret TEXT and NUMBER values as date in your statements.
If you don't need extra processing for your date values, I'd recommend going for the first solution as it should be faster because it merely compares TEXTs rather than parsing and extracting a date from them, then comparing the extracted date (I haven't compared the speed of the two approaches, so don't take my word for it on this one). This approach also has less code to write and maintain and the code is easier to read.
Sources:
SQLite data type - for the validity of comparing two TEXT values
SimpleDateFormat - Android documentation
You can use dates in yyyy-MM-dd format directly, JDBC will understand it. Assuming we a have a table t1 with c1 of DATE type
PreparedStatement ps = conn.prepareStatement("insert into t1 (c1) values (?)");
ps.setString(1, "2001-01-01");
ps.executeUpdate();
Reading dates is simple too
ResultSet rs = st.executeQuery("select c1 from t1");
rs.next();
Date date = rs.getDate(1);
ResultSet.getDate returns result as java.sql.Date whose toString method returns date in yyyy-MM-dd format

Java Date Format

I have a table in MySQL server called Caller_List. In this table I have a single date column called call_date whose data type is Date. I have created a web page in which I have a SELECT Box for from_day (where all days 1 to 31 are stored), a SELECT box for month (where all month names from January to December are stored), a SELECT box for year (where all years from 2000 to 2012 are stored. Like I also have a SELECT box for to_day, to_month and to_year.
The problem is when I fetch these day,month and year from java servlet using request.getParameter() method, it is fetched as string data type and stored in variable called from_date and to_date. I concatenate from_day,from_month and from_year and store in the variable called from_date. Also I concatenate to_day,to_month and to_year and store in to_date. I concatenate them in the format year-month-day since MySQL understands this format.
I then pass the following query to retrieve data between these two from_date and two date:
select caller_name,call_date
from Caller_List
where call_date>='"+from_date+"' and call_date<='"+to_date+"'
I also tried the following query but in vain:
select caller_name,call_date
from Caller_List
where call_date between '"+from_date+"' and '"+to_date+"'
I also came to know that I need to convert from_date and to_date to date format before executing the query. But I am a novice in java, I do not know how to do it. Also I want the date in the format year-month-date. I do want to display time with date, please please help me!
If you only want to know how to parse a String to a Date in java, you could simplely use the SimpleDateFormat class.
final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
final Date fromDate = dateFormat.parse(from_date);
} catch (ParseException e) {
// ...
}
Assume that your from_date string is looks like 2012-09-16.
And if you want to display a date with time. You can also use the SimpleDateFormat.
final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
try {
final String displayDate = dateFormat.format(new Date());
} catch (ParseException e) {
// ...
}
The displayDate should looks like 2012-09-16 20:13:25.
One more thing, you could compare a string type and a date type in MySQL. Just make sure your date string has the pattern "yyyy-mm-dd hh:mm:ss". Of course, you should use the preparedStatement.

different date format in java after fetching from oracle

In my db max date is as : 27-FEB-12
when i am fetching data by java from db that is:
select to_char(max(CREATE_DT),'dd-mm-yyyy') from PROFILE_DETAILS;
gives me 2012-02-27 00:00:00.0
How can i convert it to: 27-FEB-12( i am trying to use indian date format)
Any idea please
I don't know why you need to_char function in your query. If you are fetching data by jdbc, oracle could give you Date object. It is in your case much easier to convert into different format (String) in future.
anyway based on your current requirement, with to_char, you get a String 2012-02-27 00:00:00.0. now you want to get another string 27-FEB-12. you could do something like below(exception handling was omitted):
final String s = "2012-02-27 00:00:00.0";
String newDateString = new SimpleDateFormat("dd-MMM-yy").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").parse(s));
this will give you 27-Feb-12
String strDate = "2012-02-27 00:00:00.0";
String TimeZoneIds = TimeZone.getDefault().getID();
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
SimpleDateFormat sdf2 = new SimpleDateFormat("dd-MMM-yyyy");
sdf2.setTimeZone(TimeZone.getTimeZone(TimeZoneIds));
try {
Date date = sdf1.parse(strDate);
String strFinalDate = sdf2.format(date);
System.out.println(strFinalDate);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
In an Oracle DATE column there is no format; the string representation you see when you select max(create_dt)) from profile_details in SQL*Plus, say, is using an implicit format mask from your NLS settings, which appears to be DD-MON-RR in that client.
You JDBC call is applying an explicit format mask, which is the right thing to do if you want Java to treat it as a String, not least because it may have different NLS settings. But your mask doesn't match what you say you want; you're specifying DD-MM-YYYY when you want DD-MON-RR.
But it also looks like you're probably retrieving the value from the JDBC call with a getDate() call, and it's being implicitly cast back to a Java Date object type. If you want to treat it as a Date in Java, then you don't need the to_char in your select, and you need to use Java tools (e.g. SimpleDateFormat as #Andrew Logvinov suggests) to turn it into a String as needed. If you're only ever treating it as a String - for immediate display, say - then use getString() instead, and fix your date format mask in the query.
Edit
If you retrieve the value from JDBC with getDate() and want to see the value as a String in the format you specified, you need to do something like:
Date raw_date;
String string_date;
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy");
raw_date = <resultSet>.getDate(1);
string_date = sdf.format(raw_date);
select to_char(max(CREATE_DT),'dd-MON-yy') from PROFILE_DETAILS;

Categories