I have this Java method that process a ResultSet.
protected void populateDto(String[] rowSet, ResultSet rs, String[] columunsNames) throws SQLException {
for (int i = 0; i < rowSet.length; i++) {
rowSet[i] = rs.getString(columunsNames[i]);
}
}
As you can see all result are treated as String type (getString is used whatever is the column type). When a Date column is encountered it is automatically converted into a String. The resulting date will appear similar to this one:
2012-08-01 16:10:47.0
I have modified the above script, creating something like that:
protected void populateDto(String[] rowSet, ResultSet rs, String[] columunsNames) throws SQLException {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (int i = 0; i < rowSet.length; i++) {
Object o = rs.getObject(columunsNames[i]);
if (o instanceof Date) {
rowSet[i] = formatter.format((Date)o);
} else {
rowSet[i] = (String)o;
}
}
}
This method treat everything as Object, after, will check if that Object is an instance of Date. If this is true it will formatted in according to the formatter. The problem is that in this way the data returned is like:
2012-08-01 00:00:00.0
Why?
Update 1 - Last working method implementation:
protected void populateDto(String[] rowSet, ResultSet rs, String[] columunsNames, SimpleDateFormat formatter) throws SQLException {
Timestamp ts = null;
for (int i = 0; i < rowSet.length; i++) {
Object obj = rs.getObject(columunsNames[i]);
if (obj instanceof Date) {
ts = rs.getTimestamp(columunsNames[i]);
rowSet[i] = formatter.format(ts);
} else {
if(obj!=null)
rowSet[i] = obj+"";
else
rowSet[i] = "";
}
}
}
java.sql.Date does not store info about time:
To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.
This method treat everything as Object, after, will check if that Object is an instance of Date.
Instead of date use java.sql.Timestamp, with this you can get Date as well as Time either you persist data or fetch data.
Update 1
You can have a general method like
public Timestamp getTimestamp(int columnIndex) throws SQLException {
Object value = getObject(columnIndex);
if (value instanceof Timestamp) return (Timestamp) value;
}
this will return the date and time and you could call by passing the column index.
Related
In my website, I can select a date range and list all the transactions within the date range. My test case is to verify whether listed transactions dates are within the selected date range .
This is my code. I get all the transaction dates into a LinkedList. Comp_Dates method will compare the actual date is within the ‘From’ and ‘To’ dates.
The problem is this code will always return True. I have changed the FromDate and ToDate to test the false scenario, But still code will return True.
Can you please help? What’s the problem in this code?
//Set From Date
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_dtDateFrom_txtDate")).sendKeys(Keys.chord(Keys.CONTROL, "a"),"01/03/2016");
//Set To date
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_dtDateTo_txtDate")).sendKeys(Keys.chord(Keys.CONTROL, "a"),"30/04/2016");
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_btnList")).click();
List<WebElement> Date =
driver.findElements(By.xpath(".//* [#id='ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_stxOutstandingTransactions_gvOSTransactions']/tbody/tr[*]/td[1]"));
List<String> Dates = new LinkedList<String>();
for(int i=0;i<Date.size();i++)
{
Dates.add(Date.get(i).getText());
System.out.println(Dates);
}
boolean result = comp_Dates(Dates);
if (result=true)
{
System.out.println(result + ", Address are within the range");
}
else
{
System.out.println(result + ", Addresses are not within the range. Test Case Failed");
}
}
private static boolean comp_Dates(List<String> Dates) {
try
{
SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy");
//Date date = fmt.parse("2013-05-06");
String FromDate= "01/05/2016";
String ToDate= "30/06/2016";
java.util.Date Fdate =fmt.parse(FromDate);
java.util.Date Tdate =fmt.parse(ToDate);
for(String e : Dates)
{
java.util.Date ActualDate = fmt.parse(e);
if (ActualDate.compareTo(Fdate)>=0 & ActualDate.compareTo(Tdate)<=0 );
{
return true;
}
}
}
catch (Exception ex ){
System.out.println(ex);
}
return false;
}
}
Transactions dates in Linked list is [18/04/2016, 14/04/2016, 13/04/2016]
I have specified dates as below in the code.
String FromDate= "01/05/2016";
String ToDate= "30/06/2016";
When compare these dates, code should return false as dates doesn’t fall on within From and To dates. But it returns True. What am I doing wrong here?
Thanks
When you are returning true, it will exit the function whenever it founds a date in the range. Thus it would not check for all dates in the list.
If you want to check for all dates, proper comp_Dates method could be:
//Set From Date
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_dtDateFrom_txtDate")).sendKeys(Keys.chord(Keys.CONTROL, "a"), "01/03/2016");
//Set To date
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_dtDateTo_txtDate")).sendKeys(Keys.chord(Keys.CONTROL, "a"), "30/04/2016");
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_btnList")).click();
List<WebElement> Date =
driver.findElements(By.xpath(".//* [#id='ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_stxOutstandingTransactions_gvOSTransactions']/tbody/tr[*]/td[1]"));
for (int i = 0; i < Date.size(); i++) {
String date = Date.get(i).getText();
boolean result = comp_Dates(date);
if (result) {
System.out.println(result + ", Address are within the range");
} else {
System.out.println(result + ", Addresses are not within the range. Test Case Failed");
}
}
private static boolean comp_Dates(String date) {
try {
SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy");
String FromDate = "01/05/2016";
String ToDate = "30/06/2016";
java.util.Date Fdate = fmt.parse(FromDate);
java.util.Date Tdate = fmt.parse(ToDate);
java.util.Date ActualDate = fmt.parse(date);
if (ActualDate.compareTo(Fdate) >= 0 && ActualDate.compareTo(Tdate) <= 0) {
return true;
}
} catch (Exception ex) {
System.out.println(ex);
}
return false;
}
N.B: There are many typos in your code. You should fix these.
I have trouble finding elements, here is my code:
public static void main(String[] args) {
BufferedReader br = getFileReader("reader.csv");
ArrayList<Monitoring> col = getCollection(br);
//sort the collection on 'beginTime'
for (Monitoring x : col)
System.out.println(x.toString());
BeginTimeComparator beginTime = new BeginTimeComparator();
Collections.sort(col,beginTime);
System.out.println("Begin time:");
for (Monitoring x : col)
System.out.println(x.toString());
This is the part I have trouble with, I don't know how to search en get back the object with endTime 2015-03-10.
BTW this is one line of cvs data:
UnitId;BeginTime;EndTime;Type;Min;Max;Sum
14100072;2015-03-10 07:12:20;2015-03-10 7:13:20;Gps/GpsAccuracyGyroBias;0;0;0
//find the amount of elements that were sent on 'endTime' = 2015-03-10 (just the date)
EndTimeComparator endTime = new EndTimeComparator();
String findThis = "2015-03-10";
Collections.sort(col, endTime);
for(Monitoring x : col){
if(x.getEndTime().equals(findThis)){
System.out.println("Here is 'endTime= 2015-03-10' :");
System.out.println(x.toString());
}
}
I have tried this but both didn't work:
int index = Collections.binarySearch(col, findThis.toString(), null);
System.out.println("Here is 'endTime= 2015-03-10' :");
System.out.println(index);
Guessing that getEndTime() returns a LocalDateTime you can't compare a string with a type of LocalDateTime. You could try to parse the LocalDateTime to LocalDate and fill the 'findThis' variabel with a type of LocalDate.
Because code says more than a 1000 words:
EndTimeComparator endTime = new EndTimeComparator();
Collections.sort(col, endTime);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate findThis = LocalDate.parse("2015-03-10", dtf);
System.out.println("Here is 'endTime= 2015-03-10' :");
for (Monitoring x : col) {
if (x.getEndTime().toLocalDate().equals(findThis)) {
System.out.println(x.toString());
}
}
You need to provide Comparator for that null or Monitoring should implement comparable (both of them should compare items by time field that you need).
Collections.binarySearch(col, findThis.toString(), null);
According to the example data you provided
UnitId;BeginTime;EndTime;Type;Min;Max;Sum
14100072;2015-03-10 07:12:20;2015-03-10 7:13:20;Gps/GpsAccuracyGyroBias;0;0;0
endTime is "2015-03-10 7:13:20", not "2015-03-10", so using equals will not work. Instead, you could try using startsWith:
String findThis = "2015-03-10";
for (Monitoring x : col) {
if (x.getEndTime().startsWith(findThis)) {
System.out.println("Here is 'endTime= 2015-03-10': ");
System.out.println(x.toString());
}
}
Or even better: Instead of storing the begin and end times as strings, convert them to Date objects or similar when you read the objects from CSV.
Got this code:
System.out.println("Introduce salary: ");
Scanner alpha8 = new Scanner(System.in);
String salary = alpha8.nextLine();
int salaryNew = 0;
if(salary .isEmpty()){
salary = null;
}else{
salaryNew = Integer.parseInt(salary);
}
How can i make this to output only 1 variable from the IF? Because if the introduced value is null (blank space from scanner, like enter) sets salary to null wich i use later on.
The thing is that i either need a "null" or an "int value".
In the "else" i cannot do this:
salary = Integer.parseInt(salary);
because id get an error, neither i can parse int into to null.
And this methodto convert dates:
public static Date changeDate(String introducedDate) throws ParseException {
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
java.util.Date sqlDate = sdf.parse(introducedDate);
java.sql.Date newSqlDate= new java.sql.Date(sqlDate.getTime());
return newSqlDate;
}
If introducedDate is null it will throw an exception, how can i change that method to return NULL if introduced date is NULL too?
Part 1
The thing is that i either need a "null" or an "int value".
If you want to have an integer value which is nullable, use the wrapper class Integer:
Integer salaryNew = null;
if (!salary.isEmpty()) {
salaryNew = Integer.parseInt(salary);
}
Part 2
If introducedDate is null it will throw an exception, how can i change that method to return NULL if introduced date is NULL too?
You need to check the value of the parameter before you do any work on it (See #nem's answer, since he beat me to that half).
Check out #azurefrog's answer for your first question.
If introducedDate is null it will throw an exception, how can i change that method to return NULL if introduced date is NULL too?
public static Date changeDate(String introducedDate) throws ParseException {
if(introducedDate == null) { // ADD THIS CHECK
return null;
}
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
java.util.Date sqlDate = sdf.parse(introducedDate);
java.sql.Date newSqlDate= new java.sql.Date(sqlDate.getTime());
return newSqlDate;
}
you can do -
if(salary != null && ! salary.isEmpty() )
{
return Integer.parseInt(salary);
}else{
return null;
}
for your second part add this if condition before doing any date format-
if(introducedDate == null) {
return null;
}
I'm calling a plsql package procedure from Java. This procedure has an type parameter which carries a timestamp. When I'm setting a timestamp parameter directly to a procedure I can specify a Calendar object to declare the time zone to use e. g.
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
statement.setTimestamp(1, new Timestamp(calendar.getTimeInMillis()), calendar);
Is there a way to declare a timezone when using an oracle.sql.ARRAY or oracle.sql.STRUCT ?
The used types are declared as follows:
CREATE OR REPLACE TYPE "TY_EVENT_OBJECT"
AS
OBJECT
(
timestamp_event date,
state number(15),
parameter_name varchar2(248),
value number(15)
);
CREATE OR REPLACE TYPE "TY_EVENTS"
AS
TABLE OF TY_EVENT_OBJECT;
The Type TY_EVENTS is one parameter of the plsql procedure i have to use.
There is no way to simply pass a calendar which will be used for time zone conversion when you use user defined oracle types. When oracle.sql.ARRAY and oracle.sql.STRUCT are used, the ojdbc uses local calendar to convert java.sql.Date to oracle.sql.DATE so the actual date stored in database, in your case, is local time without timezone.
So if you want the date to be stored to database in UTC you will have to convert the java.sql.Date to oracle.sql.DATE manually by using UTC calendar.
Here is how you could do it:
Implement the SQLData interface and override the methods.
note:
-getSQLTypeName has to return the actual type name as defined in database, otherwise doesn't work.
-we use java.sql.Date below, it's important. So, if you want java.util.Date outside of TyEventObject you could create a setter/getter that does the conversion
public class TyEventObject implements SQLData {
private String sqlTypeName = "TY_EVENT_OBJECT";
private java.sql.Date timestampEvent;
private long state;
private String parameterName;
private long value;
#Override
public String getSQLTypeName() throws SQLException {
return sqlTypeName;
}
#Override
public void readSQL(SQLInput stream, String typeName) throws SQLException {
sqlTypeName = typeName;
// Reading date in UTC time
OracleJdbc2SQLInput oracleStream = (OracleJdbc2SQLInput) stream;
DATE oracleDate = (DATE)oracleStream.readOracleObject();
if( oracleDate != null) {
timestampEvent = oracleDate.dateValue( Calendar.getInstance(TimeZone.getTimeZone("UTC")));
} else {
timestampEvent = null;
}
state = stream.readLong();
parameterName = stream.readString();
value = stream.readLong();
}
#Override
public void writeSQL(SQLOutput stream) throws SQLException {
// Writing timestamp in UTC time
OracleSQLOutput oracleStream = (OracleSQLOutput) stream;
if( timestampEvent != null) {
DATE oracleDate = new DATE( timestampEvent, Calendar.getInstance(TimeZone.getTimeZone("UTC")));
oracleStream.writeOracleObject( oracleDate);
} else {
stream.writeDate( null);
}
stream.writeLong( state);
stream.writeString( parameterName);
stream.writeLong( value);
}
// add public getters and setters
}
Now you create an array of these TyEventObject objects to pass to plsql procedure like this (note that Array is java.sql.Array):
// I assume that your event objects that you want to save are in the list eventObjects
TyEventObject[] entries = new TyEventObject[ eventObjects.size()];
for( int i=0; i < eventObjects.size(); i++) {
entries[i] = new TyEventObject();
// You set the properties here
// entries[i].setTimestampEvent( eventObjects.get( i).getTimestampEvent());
}
Array dataObjectArray = connection.createArrayOf( "TY_EVENTS", entries);
And finally you call you plsql procedure like usual:
CallableStatement cs = connection.prepareCall("{call ProcedureName( ?)}");
cs.setObject(1, dataObjectArray, Types.ARRAY);
cs.execute();
cs.close();
I'm currently using the Spring framework, though I'm not sure if this is directly the issue. I'm getting the following error:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: java.sql.Timestamp cannot be cast to java.sql.Date
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:929)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:824)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:798)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
#SuppressWarnings({ "rawtypes", "unchecked"})
public List getAllByFilter( String collectionPeriod,String sYear, String submission) {
// TODO Auto-generated method stub SELECT_QUERY_BY_COLL_MSTR
List<CollectionCalendar> orgs1 = new ArrayList<CollectionCalendar>();
List<Map<String,Object>> rows1 = null;
String query="SELECT_QUERY_BY_COLL_MSTR";
if("All".equalsIgnoreCase(sYear) && "All".equalsIgnoreCase(collectionPeriod)){
query="SELECT_QUERY_BY_COLL_MSTR_SUBMISSION";
rows1 = getJdbcTemplate().queryForList(p.getProperty(query),new Object[] {submission});
}else if(!"All".equalsIgnoreCase(sYear) && "All".equalsIgnoreCase(collectionPeriod)){
query="SELECT_QUERY_BY_COLL_MSTR_SUBMISSION_YEAR";
rows1 = getJdbcTemplate().queryForList(p.getProperty(query),new Object[] {sYear,submission});
}else if("All".equalsIgnoreCase(sYear) && !"All".equalsIgnoreCase(collectionPeriod)){
query="SELECT_QUERY_BY_COLL_MSTR_SUBMISSION_COLLECTION";
rows1 = getJdbcTemplate().queryForList(p.getProperty(query),new Object[] {collectionPeriod,submission});
}else if(!"All".equalsIgnoreCase(sYear) && !"All".equalsIgnoreCase(collectionPeriod)){
rows1 = getJdbcTemplate().queryForList(p.getProperty(query),new Object[] {sYear,collectionPeriod,submission});
}
System.out.println("hellooooooooooooooooooo");
for (Map row : rows1) {
System.out.println("row------"+row);
CollectionCalendar collectionCalendar = new CollectionCalendar(row.get("COLL_KEY").toString(),
(Date)row.get("COLL_OPEN_DT"),
(Date)row.get("COLL_CLOSE_DT"),
(Date)row.get("COLL_AVLBL_DT"),
row.get("COLL_ACAD_YR").toString(),
row.get("COLL_NAME").toString(),
row.get("COLL_DESC").toString(),
row.get("SUBM_DESC").toString(),
row.get("UPDATE_USER").toString());
//(Timestamp) row.get("UPDATE_DTTM"));
orgs1.add(collectionCalendar); (COMMENTED THIS OUT BUT STILL GETTING ERROR)
}
return orgs1;
}
public CollectionCalendar(String colKey,Date opDate,Date clDate,Date avDate,String sYear,String submission,String collectionPeriod,String subDesc,String updateUser){
setCollKey(colKey);
setOpenDate(opDate);
setCloseDate(clDate);
setAvailDate(avDate);
setsYear(sYear);
setSubmission(submission);
setCollectionPeriod(collectionPeriod);
setSubDesc(subDesc);
setUpdateUser(updateUser);
//setUpdateTime(updateTime);
}
What I have is a search form that queries the DB and returns results into a table. I'm pulling data from Oracle DB table where the column type is Date but for some reason it's telling me that it cannot cast from a Timestamp value. I'm not requesting a Timestamp value at all.
Any help is greatly appreciated.
It appears that one or all of COLL_OPEN_DT, COLL_CLOSE_DT, and COLL_AVLBL_DT is a timestamp in the database. Luckily java.sql.Timestamp extends java.util.Date.
Option 1
Change the date elements in the CollectionCalendar class to be java.util.Date
Option 2
Create a class with a mehod that takes a java.sql.Timestampand returns ajava.sql.Date`
Here is a simple example:
class Blammy
{
static final java.sql.Date convertTimestamp(final java.sql.Timestamp timestamp)
{
java.sql.Date returnValue;
if (timestamp != null)
{
returnValue = new java.sql.Date(timestamp.getTime());
}
else
{
returnValue = null; // an exception might be better here.
}
return returnValue
}
}
Then change the code above to something like this:
...
Blammy.convertTimestamp(row.get("COLL_OPEN_DT")),
...
Option 3
Something else (that I did not think of).