I have two applications with different time zones.
Application 1: -Duser.timezone=Australia/Darwin
Application 2: -Duser.timeZone=Asia/Kolkata
Application 1 inserts TimeStamp based on Zone1 and Application2 inserts TimeStamp based on Zone2.
While fetching data from Application1, Zone conversion is not done.
Instead it displays the same result.
Values inserted to DB:
2019-02-19 15:39:40 - Application1
2019-02-19 11:40:09 - Application2
Output when fetched from Application 1/ Application2
Time Stamp from DB: 2019-02-19 15:39:40.0
Time Stamp from DB: 2019-02-19 11:40:09.0
For Example , if data is read from Application 1, time Stamp should be displayed according to Austria/Darwin.
How to achieve this?
Here is the code snippet.
String selectSQL = "select createdtime from TZ_TEST6";
PreparedStatement ps = conn.prepareStatement(selectSQL);
ResultSet rs = ps.executeQuery(selectSQL );
while (rs.next())
{
Timestamp timestamp = rs.getTimestamp(1);
System.out.println("Time Stamp from DB: " +timestamp);
}
Related
I have problem with HQL where I am setting the query parameters. One of them is Date. When I debug the code there is Date with time entering the method. I set the parameter using setParameter(timestamp, new Timestamp(date.getTime())) or query.setTimestamp...etc etc I used many combinations...
When I use p6spy to examine the SQL comming from app to the DB there is only '29-Jan-21' or other date without time.
I am using hibernate 5.1.0 final and postgre DB. I'll be glad for any help.
Example:
Query query = getSessionFactory().getCurrentSession().createQuery("SELECT user FROM UserEntity cr WHERE user.userStatus.id = :statusId AND :timestamp >= user.valid_to");
This is how I tried to set the timestamp parameter:
query.setParameter("timestamp", new Timestamp(date.getTime()));
query.setParameter("timestamp", date, TimestampType.INSTANCE);
query.setTimestamp("timestamp", date);
query.setTimestamp("timestamp", new Timestamp(date.getTime()));
Problem is that the generated SQL replace timestamp by '29-Jan-21' or other date I choose but without time. The date parameter comes to the method from UI and it contains full date with time.
I'm using Java 8 with Spring's JdbcTemplate and Oracle 12.1,
I want to update record and get the exact time record was updated
jdbcTemplate.update(UPDATE_SQL, null);
Currently it returns (int) the number of rows affected, but I want the exact updated date
Must I send a new request to get current time which may be inaccurate?
More exact will be to save in column updated date, but then to execute another SQL
Is there another option to get updated date in one query?
Obviously, I don't want to use get date from code also (as new Date()) also because server time is/can be different than DB Time
You decided to use JDBCTemplate most probably to simplify the code in comparison to plain JDBC.
This particular problem IMHO makes the plain JDBC solution as proposed in other answer much simpler, so I'd definitively recommend to get the database connection from JDBCTemplate and make the insert in a JDBC way.
The simplest solution using JDBCTemplate that comes to my mind is to wrap the insert in a PROCEDURE and return the timestamp as an OUT parameter.
Simple example (Adjust the time logik as required)
create procedure insert_with_return_time (p_str VARCHAR2, p_time OUT DATE) as
BEGIN
insert into identity_pk(pad) values(p_str);
p_time := sysdate;
END;
/
The call is done using SimpleJdbcCall
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate).withProcedureName("insert_with_return_time");
SqlParameterSource params = new MapSqlParameterSource().addValue("p_str", str);
Map<String, Object> out = jdbcCall.execute(params);
The Map contains the returned value e.g. [P_TIME:2019-10-19 11:58:10.0]
But I can only repeat, in this particular use case is IMHO JDBC a rescue from JDBCTemplate;)
You're right that passing new Date() would store the server time rather than the DB time.
To store the DB time you can set your timestamp to the DB system timestamp systimestamp then you could run a query to retrieve that row and its updated timestamp.
If you want to update the row and get the updated timestamp in a single execution then you could do the following using RETURNING INTO where TimestampUpdated is your column name:
Connection con = ...;
String sql = "UPDATE TableName SET <updates> , TimestampUpdated = systimestamp RETURNING TimestampUpdated INTO ?";
CallableStatement statement = con.prepareCall(sql);
statement.registerOutParameter(1, Types.TIMESTAMP);
int updateCount = statement.executeUpdate();
Timestamp timestampUpdated = statement.getInt(1);
System.out.println("Timestamp Updated = " + timestampUpdated);
Here is a related link doing this with JdbcTemplate
I'm using Java 8 with Spring's JdbcTemplate and Oracle 12.1,
I want to update record and get the exact time record was updated
jdbcTemplate.update(UPDATE_SQL, null);
Currently it returns (int) the number of rows affected, but I want the exact updated date
Must I send a new request to get current time which may be inaccurate?
More exact will be to save in column updated date, but then to execute another SQL
Is there another option to get updated date in one query?
Obviously, I don't want to use get date from code also (as new Date()) also because server time is/can be different than DB Time
You decided to use JDBCTemplate most probably to simplify the code in comparison to plain JDBC.
This particular problem IMHO makes the plain JDBC solution as proposed in other answer much simpler, so I'd definitively recommend to get the database connection from JDBCTemplate and make the insert in a JDBC way.
The simplest solution using JDBCTemplate that comes to my mind is to wrap the insert in a PROCEDURE and return the timestamp as an OUT parameter.
Simple example (Adjust the time logik as required)
create procedure insert_with_return_time (p_str VARCHAR2, p_time OUT DATE) as
BEGIN
insert into identity_pk(pad) values(p_str);
p_time := sysdate;
END;
/
The call is done using SimpleJdbcCall
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate).withProcedureName("insert_with_return_time");
SqlParameterSource params = new MapSqlParameterSource().addValue("p_str", str);
Map<String, Object> out = jdbcCall.execute(params);
The Map contains the returned value e.g. [P_TIME:2019-10-19 11:58:10.0]
But I can only repeat, in this particular use case is IMHO JDBC a rescue from JDBCTemplate;)
You're right that passing new Date() would store the server time rather than the DB time.
To store the DB time you can set your timestamp to the DB system timestamp systimestamp then you could run a query to retrieve that row and its updated timestamp.
If you want to update the row and get the updated timestamp in a single execution then you could do the following using RETURNING INTO where TimestampUpdated is your column name:
Connection con = ...;
String sql = "UPDATE TableName SET <updates> , TimestampUpdated = systimestamp RETURNING TimestampUpdated INTO ?";
CallableStatement statement = con.prepareCall(sql);
statement.registerOutParameter(1, Types.TIMESTAMP);
int updateCount = statement.executeUpdate();
Timestamp timestampUpdated = statement.getInt(1);
System.out.println("Timestamp Updated = " + timestampUpdated);
Here is a related link doing this with JdbcTemplate
I am executing following query in psql via console and getting output :
select details
from history_transactions
,history_operations
where history_operations.transaction_id = history_transactions.id
and type = 3
and created_at >= NOW() - INTERVAL '5 minutes'
However when I call this code from my java program, it is not returning any output. The ResultSet is null. PFB my code:
Connection conn = getConnection();
java.sql.Statement stmt = null;
String sql ="select details from history_transactions , history_operations where history_operations.transaction_id=history_transactions.id and type =3 and created_at >= NOW() - INTERVAL '5 minutes'";
try{
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while(rs.next()) {
System.out.println("Inside resultset");
}
}
catch(Exception e)
{
e.printStackTrace();
}
Any idea where I am going wrong?
I am not getting any exception as well.
Note: If I change the interval from 5 minute to 6 hours or more it is working and giving me output. If I change the interval < 5 hours then the resultset is null. However If I login to psql server and execute the query as it is in the code. I am getting output.
I am using java version "1.8.0_151" and PostgreSQL JDBC 4.2 Driver, 42.2.1 - as per https://jdbc.postgresql.org/download.html - it is the suitable driver.
The PostgreSQL NOW() function returns a timestamp with time zone value. In order to use that value against a column of type timestamp (without time zone) PostgreSQL needs to implicitly CAST that value to match the column type. However, testing shows that if the client and the server are set to different time zones the result of that CAST can be different when connected via psql vs. when connected via JDBC. For example:
Server time zone: UTC
Client time zone: America/Denver, a.k.a. "MST/MDT", currently UTC-7
When connected via psql,
SELECT CAST(CAST(NOW() AS timestamp) AS varchar)
returns the UTC value
2018-02-05 22:40:25.012933
but when connected via JDBC the same query returns the MST value
2018-02-05 15:40:57.288587
To return the UTC value under JDBC we can execute
set time zone 'UTC'
before running our SELECT query.
I am writing a Client Server Application now when the Client sends a command to the Server the Record in the SQL Database is updated and On Update a Timestamp is set on a field. But now I want to read all the Users in the SQL Database that where online in the last hour with the Timestamp.
So this is how far I am:
SELECT username FROM users WHERE lastonline...
lastonline is the field with the timestamp of the users last update. I now have no Idea how to check if he was online in the last hour.
I thank you for you help.
Select username FROM user WHERE lastoinline>"date now - 1 hour" AND lastoinline<="date now"
Date dеNow = new Date();
Date веBefore = tdNow; tdBefore.setHours(tdBefore.getHours()-1);
String query = "SELECT username FROM user WHERE lastonline>='"+(dtBefore.getTime/1000)+"' AND lastonline<='"+(dtNow.getTime/1000)+"'
"
Compare the current hour with the hour on the timestamp's record.
If you are using sql server:
SELECT DATEPART(hh, GETDATE()) --current hour
SELECT DATEOART(hh, ColumnStoredInDB) --stored hour
Spoiler: Simply take the ColumnStoredInDB from the current hour and if the difference is < 1 that user has been in the system for the last hour. If the difference >=1 you can skip that record