Date is different that in database - java

In my Quarkus app I have object which is the same as a table in database that have a java.sql.Timestamp createDate field. In database example date is shown as a: 2022-02-17 18:16:00 in PST time but when I get the object through JPA from MySQL database as a Timestamp is: 2022-02-18 02:16:00.0 which looks like UTC time.
In application properties I have:
quarkus.hibernate-orm.jdbc.timezone = America/Los_Angeles
which means that database is configured in PST time.
Any ides why time zone is different in java object from database data?

I met the same issue.
In the datebase table time field, the time is different 8 oclock from the app server.

Related

Store and retrieve a date in MySQL without any timezone information using MySQL Connector/J 8.0

We are now in the process of updating the MySQL Connector/J of a Spring Boot application from version 5 to 8 (we are actually updating the Spring Boot version from 2.0 to 2.1, but I don't think it's relevant for our problem).
After upgrading the connector (the database remains the same: MySQL 5.7) we found that all the DATETIME values stored in the database were being shifted by the timezone difference between the server and the client (UTC and UTC+1). If we, for example, try to read a value like 2019-01-01 02:17:00 we are getting 2019-01-01 03:17:00.
We are aware that the new connector is the one making that time shift but we need our dates to be timezone independent. According to the documentation of MySQL 5.7 it looks like DATETIME is the way to go:
MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such as DATETIME.)
The only thing we can do right now is either downgrade the connector to previous version or change all the DATETIME columns to a BIGINT.
Is there any way of storing a date and a time without any timezone automatic conversion in MySQL?
Adding timezone to connection string should solve this problem. Try to add following text to your connection url:
useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=CET
In the past I've used this trick to make sure that the effective server time zone is the same as the client time zone:
String connectionUrl = "jdbc:mysql://localhost:3307/mydb?useUnicode=true"
+ "&serverTimezone=" + ZoneId.systemDefault().getId();
System.out.println(connectionUrl);
// jdbc:mysql://localhost:3307/mydb?useUnicode=true&serverTimezone=America/Denver
Connection conn = DriverManager.getConnection(connectionUrl, myUid, myPwd);

Oracle session timezone: Can Oracle DB session convert java.sql.Date to correct timezone?

We have an audit table( Columns/Types: ID/Number,.. Audited_Date/Date) which logs audit entries using prepared statements. Until now, for different contexts we set the database session timezone for the connection, after which we were using the CURRENT_DATE attribute for the audited_date column. THIS MEANT THAT THE DATE INSERTED INTO THE COLUMN IS IN THE TIMEZONE OF THE CONNECTION WHICH IS IMPORTANT.
Now, we have a new requirement to add different dates based on the supplied timestamps for the audit logs. Similar to the previous approach where the auditing engine didn't have to worry about the timezone, is there a way to set the date for the column, WITHOUT having to do something like this:
TimeZone timeZone = TimeZone.getTimeZone(timezone);
calendar.setTimeZone(timeZone);
preparedStatement.setDate(4, new java.sql.Date(userTimestampMillis), calendar);
I would really like NOT to do this because the timezone attribute is decided based on multiple attributes like system environments, and other parameters. The application uses ALTER SESSION SET TIME_ZONE="CONTEXT_TIMEZONE" in a global scope of the application where connections are fetched from.
Is there any way to let the DB session handle the timezone conversion?
These two approaches fail to convert the the timestamp to the DB session timezone. If i'm not wrong, they are using the JVM timezone.
FAIL1.
Timestamp timestamp = new Timestamp(userTimestampMillis);
preparedStatement.setTimestamp(4, timestamp);
FAIL2.
preparedStatement.setObject(4, new java.sql.Date(userTimestampMillis));
Any documentation is greatly appreciated.
DATEs are not time zone aware, so you probably want to work with something in the TIMESTAMP WITH TIME ZONE data type. You say you can correctly set the database session time zone, so you're mostly there. Say you're in Los Angeles and my database session is in Chicago:
alter session set time_zone = 'America/Chicago';
Session altered.
select current_timestamp from dual;
CURRENT_TIMESTAMP
---------------------------------------------
2018-07-27 20:30:28.672000000 AMERICA/CHICAGO
select cast( current_timestamp at time zone 'America/Los_Angeles' as date ) as d from dual;
D
-------------------
2018-07-27 18:30:28
So you basically need to use AT TIME ZONE to convert the TIMESTAMP WITH TIME ZONE into the correct time zone, then use CAST ( ... AS DATE ) to turn that into a DATE, which basically just trucates off the time zone information and doesn't do any conversion.

JDBC and oracle database timezone handling

I have created sample table in oracle DB as below
"CREATED_ON" TIMESTAMP (6),
"CREATED_ON_TIMEZONE" TIMESTAMP (6) WITH TIME ZONE,
"TIMEZONE_GMT" TIMESTAMP (6) WITH TIME ZONE
and inserted values from java as below
preparedStatement.setTimestamp(1, new Timestamp(new Date().getTime()));
preparedStatement.setTimestamp(2, new Timestamp(new Date().getTime()));
preparedStatement.setTimestamp(3, new Timestamp(new Date().getTime()) ,Calendar.getInstance(TimeZone.getTimeZone("UTC")));
JVM timezone in ASIA/CALCUTTA. I have used SQL developer to query data.
I just wanted to clear my understanding
The first column stored value as per local JVM without timezone since dataType is only timestamp i.e 29-NOV-17 07.04.28.014000000 PM. so for column with timstamp datatype DB stores value as of local JVM which is passed by JDBC driver and there is no conversion happening either JDBC side or DB side ?
Second column store value with TIMEZONE i.e 29-NOV-17 07.04.28.014000000 PM
ASIA/CALCUTTA. So does it mean DB stores value for column with timezone information provided by JDBC driver and there is no convrsion at DB side?
I want to store value in GMT so I set third parameter as GMT , it store value in GMT but timezone was still showing as of local JVM . i.e 29-NOV-17 01.34.28.014000000 PM ASIA/CALCUTTA
I was refering below article but my observations looks totally diffrent.
http://brian.pontarelli.com/2011/08/16/database-handling-for-timezones/
Problem is Java Timestamp does not contain any time zone information.
So you insert a TIMESTAMP value into a column of TIMESTAMP WITH TIME ZONE. In such case Oracle makes an implicit cast with FROM_TZ:
FROM_TZ(<your value>, SESSIONTIMEZONE)
Command preparedStatement.setTimestamp(3, new Timestamp(new Date().getTime()) ,Calendar.getInstance(TimeZone.getTimeZone("UTC"))); would be correct only after an ALTER SESSION SET TIME_ZONE = 'UTC';

JDBC SQL Time zone

I'm using Spring with apache commons BasicDataSource.
The time zone shows as GMT via:
SELECT ##global.time_zone, ##session.time_zone;
My input is in epoch time, 1386831420000 and 1386833220000, so the query should be like this:
SELECT * FROM table WHERE AND arrival_time BETWEEN '2013-12-12 06:57:00' AND '2013-12-12 07:27:00';
I enabled SQL profiing, and this is the query that actually gets executed, so I don't get the correct results:
SELECT * FROM table WHERE AND arrival_time BETWEEN '2013-12-12 01:57:00' AND '2013-12-12 02:27:00';
Notice that the times are off by 5 hours, since I am EST-5, and the time should be in GMT.
My question is: How can I tell MySQL or Spring JDBC not to use the client time zone, and simply to always use GMT?
Please comment if there is any detail I could add to solve the issue.
Try explicitly converting the date string into a date type using TO_DATE (or implementation specific date converter function)
SELECT *
FROM table
WHERE arrival_time BETWEEN
TO_DATE('2013-12-12 06:57:00', 'YYYY-MM-DD HH24:MI:SS')
AND
TO_DATE('2013-12-12 07:27:00', 'YYYY-MM-DD HH24:MI:SS')
The above example is in Oracle SQL but the principle of explicitly casting a date string to a date type is common throughout SQL implementations.
It sounds like the JDBC driver isn't properly detecting Mysql's time zone setting. You may need to specify the server's time zone in the connection string. Try adding
serverTimezone=UTC&useTimezone=true
to the connection string. For more information, refer to the JDBC doc at http://cs.wellesley.edu/~cs304/jdbc/connector-j.html#connector-j-reference

mapping dates in hibernate and mysql

We have an app in which we are using hibernate with mysql db.
We have a db script import.sql which have some insert into statements and we also have some date fields in db like start_date end_date in which we are string dates in default format, that is,YYYY-MM-DD.
Now issue is at the time of retrieving/comparing dates hibernates showing strange behaviour for example suppose if we have a date 2012-01-30 then hibernate reads in proper format that is, Jan 30 2012, but if we have a date like 2012-02-06 then hibernate reads as June 02 2012. my DAO for comparing and retrieving result is as follows
public final List<Record> getPastRecords(final java.util.Date currentDate) {
List<Record> pastRecord = session.createCriteria(Record.class)
.add(Restrictions.lt("endTime", currentDate))
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
return pastRecord;
}
Any idea what I am doing wrong?
without detailed code explanation guessing what may be the problem is very hard through i guess
it may be because of java.util.Date try to use java.sql.Date as when you call methods/constructors of libraries that deal with database better to use wrapper of java.util.Date which is java.sql.Date.
refer http://www.theresearchkitchen.com/archives/58

Categories