What Date types are timezone specific? - java

I have a calendar object with timezone specific. I want to update my sql server table using this object. However, it throws an error if I use calendar object in my unit test. I use hsqldb to test it with datetime as column type.
Therefore, I need to use different type for time. I tried using Timestamp object, it works, but it is not timezone specific. Here is my code:
private SqlParameterSource getParameters(StudyEvent studyEvent) {
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue(STUDY_ID, studyEvent.getStudy().getId());
parameters.addValue(STUDY_DATE, new Timestamp(getDate(studyEvent.getStudy().getStudyDate()).getTimeInMillis()));
//studyEvent.getStudy().getStudyDate() returns long value of time (epoch time)
}
private Calendar getDate(long time) {
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("America/New_York"));
calendar.setTimeInMillis(time);
return calendar;
}
In new Timestamp(.....) code, it won't be timezone specific which I need. What are other Date type object I can use so it is converted from Calendar and add it to sql server with timezone specific?
Edit:
I have a piece of code using prepared statement that allows me to use timestamp and timezone like this:
private long insertStudy(StudyEvent event) {
KeyHolder keyHolder = new GeneratedKeyHolder();
int records = jdbcTemplate.getJdbcTemplate().update(connection -> {
PreparedStatement statement = connection.prepareStatement(insertStudy, new String[] { STUDY_ID });
int index = 1;
statement.setTimestamp(index, new java.sql.Timestamp(Instant.now().toEpochMilli()), CALENDAR);
return statement;
}, keyHolder);
return keyHolder.getKey().longValue();
}
PreparedStatement.setTimestamp() looks like a possible solution, but I am not sure how to use PreparedStatement to SqlParameterSource..

Related

How to tell if timestamp from Postgres in Java is null

The code below is a snippet from a back-end REST service I have touched on. I'm wondering how to tell if a timestamp I'm getting is null. I've learned through trial and error that if the timestamp is null in the Postgres database that when I bring it into Java that if its null it will get instantiated as a new DateTime at the current time of operation. What can I do to check get and set nulls dynamically according to model data?
public List<SubscriptionEntityModel> getAllSubscriptions(PagingInfoDomainModel paging) throws Exception {
Database db = new Database();
String stmt = "{call sp_subscriptions_get_all(?, ?)}";
if(AppConfig.data.isDebug) {
logger.debug("Running database operation.. " + stmt);
}
CallableStatement sproc = db.dbEndpoint.prepareCall(stmt);
sproc.setInt(1, paging.pageCurrent);
sproc.setInt(2, paging.pageItemCount);
ResultSet rs = sproc.executeQuery();
List<SubscriptionEntityModel> subscriptions = new ArrayList<SubscriptionEntityModel>();
while(rs.next()) {
SubscriptionEntityModel subscription = new SubscriptionEntityModel();
subscription.subscriptionId = rs.getInt("subscription_id");
subscription.name = rs.getString("name");
subscription.emailAddress = rs.getString("email_address");
subscription.phoneNumber = rs.getString("phone_number");
subscription.organizationId = rs.getInt("organization_id");
subscription.createdAt = new DateTime(rs.getTimestamp("created_at"));
subscription.expiredAt = new DateTime(rs.getTimestamp("expired_at"));
subscriptions.add(subscription);
}
sproc.close();
db.destroy();
return subscriptions;
}
Check out ResultSet#wasNull
https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#wasNull()
Reports whether the last column read had a value of SQL NULL.
Hence you can use it after rs.getTimestamp() to check if the value read was SQL NULL, but note that ResultSet#getTimestamp already returns a null reference if that was the case.
https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getTimestamp(int)
the column value; if the value is SQL NULL, the value returned is null
The problem you're facing is that when you pass a null reference to the constructor of DateTime, it will be interpreted as now.
java.sql.Timestamp getTimestamp(String columnLabel) throws SQLException;
will return null if the SQL field is NULL.
The problem is the way you instantiate your DateTime object.
With JodaTime (I give this example as you don't specify the used library), executing the following code creates indeed a DateTime instance with the actual date time :
java.sql.Timestamp timestamp = null;
DateTime dateTime = new DateTime(timestamp);
So to solve your problem, what you could do is checking the returned value by the resultset.
If it is not null, use it to create the DateTime object.
Otherwise don't use it and leave to nullthe DateTime field of the SubscriptionEntityModel you are setting properties.
So instead of doing :
subscription.createdAt = new DateTime(rs.getTimestamp("created_at"));
You should do :
java.sql.Timestamp createdAt = rs.getTimestamp("created_at");
if (createdAt != null){
subscription.expiredAt = new DateTime(createdAt);
}

Insert jspinner time value to database

I have two jspinners. the one contains an HH:mm format and the other one is a simple number(int) spinner.
when SAVE button clicked I want to update a database table that contains the timeLimit (type time) and attempts (type int) columns. But I dont know how to save a jspinner value to a time type in my database.
String update = "Update qbank SET timeLimit = ? and attempts = ? where qbankID = ?";
preparedStatement = connection.prepareStatement(update);
preparedStatement.setTime(1, spinnerTime.getValue());
i tried the code above but the last part has an error saying spinnerTime.getValue is an object and setTime() requires a Time. How can I convert and object to time? or is there other way to insert a jspinner with time value to my database? any help would be appreciated!
It was just a simple overlooked problem. I just did this code.
Time time; int attempt;
time = (Time) spinnerTime.getValue();
attempt = Integer.parseInt(spinnerAttempt.getValue().toString());
String update = "Update qbank SET timeLimit = ? and attempts = ? where qbankID = ?";
preparedStatement = connection.prepareStatement(update);
preparedStatement.setTime(1, time);
preparedStatement.setInt(2, attempt);
preparedStatement.setInt(3, qbankID);
preparedStatement.executeUpdate();

Date format in an Oracle stored procedure called from Java

I am trying to use an Oracle stored procedure to update a database table. I am calling the procedure from a Java program. I want my procedure to accept dates in the format '01-01-2015' but for some reason my procedure will only accept a date if it is formatted as '01-JAN-2015'.
My stored procedure:
DELIMITER //
CREATE OR REPLACE PROCEDURE updateAward
(
p_award_id IN awards.award_id%TYPE,
p_award_date IN awards.award_date%TYPE,
p_total_amount IN awards.total_amount%TYPE,
p_number_sales IN awards.number_sales%TYPE,
p_emp_id IN awards.emp_id%TYPE
)
AS
BEGIN
UPDATE awards
SET award_date = to_date(p_award_date, 'DD-MM-YYYY'),
total_amount = p_total_amount,
number_sales = p_number_sales,
emp_id = p_emp_id
WHERE award_id = p_award_id;
COMMIT;
END;
/
The java code that calls it:
public boolean updateByID(Connection conn, String strVar, int[] intVar, double doubleVar)
{
System.out.println(strVar);
System.out.println(doubleVar);
System.out.println(intVar[0]);
System.out.println(intVar[1]);
System.out.println(intVar[2]);
try
{
String query = "{call updateAward(?,?,?,?,?)}";
CallableStatement stmt = conn.prepareCall(query);
stmt.setInt(1,intVar[0]);
stmt.setString(2, strVar);
stmt.setDouble(3, doubleVar);
stmt.setInt(4, intVar[1]);
stmt.setInt(5, intVar[2]);
stmt.executeUpdate();
return true;
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
return false;
}
The console print out of the variables being passed:
12-12-2012
65165.2
21
22
3
The error itself:
KORA-01843: not a valid month
ORA-06512: at line 1
Every solution that I have found has been to put the date format in the procedure. I believe I have done it with
award_date = to_date(p_award_date, 'DD-MM-YYYY'),
Have I written it incorrectly? Can someone please help?
Currently you are passing a String:
stmt.setString(2, strVar);
And you are parsing a String:
award_date = to_date(p_award_date, 'DD-MM-YYYY')
But you are expecting a Date in your custom type, and that is where the conversion fails. Change that to VARCHAR (or VARCHAR2) and it will work.
You're passing a string to a procedure that's expecting an Oracle date argument, via setString(). That means Oracle has to do an implicit conversion of the string to a date as part of the call, using the session/locale NLS_DATE_FORMAT, before you reach your to_date() call.
You could change your procedure argument type from awards.award_date%TYPE to varchar2, and still do the explicit conversion inside the procedure. Or you can leave the procedure signature as it is and pass the correct data type by converting it on the Java side, e.g.:
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
cStmt.setDate(2, new java.sql.Date(sdf.parse(strVar).getTime()));
And as p_date is already a date, you should not call to_date() on that, as it will do an implicit conversion back to a string (using NLS_DATE_FORMAT again) and then try to explicitly convert that back to a date using the format model you supplied, which is also likely to give a similar error. Simplify that to just:
SET award_date = p_award_date,

Tabe field status auto update checking system date using query in mysql & java

table field status auto update when checking with system date and expirydate using query in mysql & java
In my table,
tbl-member:
id, name, expirydate,status are fields.
How to use this with TRIGGER
(expirydate,systemdate)
CREATE
TRIGGER autoupdation
trigger_time UPDATE
ON tbl-member FOR EACH ROW
trigger_body
how to create trigger_body for this function...
field expirydate check with system date and auto update the status field.
here is the code use function for check-updation
#Override
public List<Member> FindExpiredMembers() throws ParseException {
List<Member> memberlistforreturn=new ArrayList<>();
List<Member> memberlist=getAllMember();
java.util.Date utilDate=new java.util.Date();
java.sql.Date sqldate=new java.sql.Date(utilDate.getTime());
for(Member i : memberlist){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date exp_Date=sdf.parse(sqldate.toString());
java.util.Date renew_Date=sdf.parse(i.getRenewDate().toString());
if(renew_Date.compareTo(exp_Date)<0){
memberlistforreturn.add(i);
i.setStatus(true);
update(i);
}
}
System.out.println(memberlistforreturn.size());
System.out.println("working...!!!!!!");
return memberlistforreturn;
}
using this function the program run on slow
This should be part of your BEFORE UPDATE trigger.
for each row begin
if new.expirydate < curdate() then
set new.status = 1; -- still active
else set new.status = 0; -- expired
end if;
end;

fetch records based on today's date

I wish to generate reports for my application, one such report requires to display list of orders given today. For that I have the following method in my ejb which returns nothing (debugged and found so):
public Collection<OrderStock> getOrderReport(String userName) {
String strQuery = null;
strQuery = "Select o from OrderStock o where o.userName.userName = :userName and o.orderDateTime = :orderDateTime";
Collection<OrderStock> c = em.createQuery(strQuery).setParameter("userName",userName).setParameter("orderDateTime", new Date(),TemporalType.DATE).getResultList();
return c;
}
How do i solve it? Why does it return nothing?
edited:
I am using mysql as backend
datatype of orderDateTime is DateTime
eg os data in orderDateTime : 2012-06-05 00:12:32
2012-06-05 11:34:42
2012-04-05 12:32:45
You have a DateTime column, and are looking for posts on a single date. I suspect this datetime column contains seconds or miliseconds since the Epoch. You can't compare times to dates, so you will have to convert the day to a time. Actually two times that describe the day.
SELECT o
FROM OrderStock o
WHERE
o.userName.userName = :userName
AND (
o.orderDateTime >= FirstSecondOfTheDay
OR o.orderDateTime <= LastSecondOfTheDay
)
Depending on your database system you can calculate these seconds (or milliseconds, i don't know your table) using the database or rather do it in java
You can not use Date() as simple as that. The date persisted in the DB will definitely have different format. So the best thing to do is to look into the method used to persist the data in the first place and use the same method to fetch back the data.
The method might by Oracle function, java method. You need to investigate further into this.
Try this for MySQL:
strQuery = "Select o from OrderStock o where o.user.userName = :userName and date(o.orderDateTime) = :orderDateTime";
Date today = DateUtils.truncate(new Date(), Calendar.DATE);
Collection<OrderStock> c = em.createQuery(strQuery).setParameter("userName",userName).setParameter("orderDateTime", today ,TemporalType.DATE).getResultList();

Categories