Two databases with the same data, are reporting different times - java

I live in Arizona, MST with no DST if it matters.
I have two different Oracle Databases, that is storing a list of holidays and weekends.
The column that stores the data is a DATE format, no time value.
But when I use the API to call the first db for holidays in Jan 2021, it reports the holiday date at midnight. But when I call for all holidays in Jan 2021 on the second db, it reports it as all holiday date as 7am.
The query that the db uses is
SELECT * FROM CLPUSER.HOL_DT WHERE TRIM(HOL_DT) >= ? AND TRIM(HOL_DT) <= ?";
The API is using Vertx-jdbc when calling the db. I have double checked the configuration of the API and the db, all are using MST.
Here are the values that are returned from the API call
DB1
"publicHolidayList": [
"holidayDate": "2021-01-01T00:00:00Z",
"holidayDate": "2021-01-02T00:00:00Z",
"holidayDate": "2021-01-03T00:00:00Z"
...
]
DB2
"publicHolidayList": [
"holidayDate": "2021-01-02T07:00:00Z",
"holidayDate": "2021-01-03T07:00:00Z"
...
"holidayDate": "2021-01-01T07:00:00Z" //appears at bottom
]
Edit: Just debugged through the code till I got to how vertx jdbc reads it from the underlining JDBC library, It is reading the HOL_DT from the jdbc as a TIMESTAMP, when the db stores it as a Date Format. When it does that, it converts to ZoneDateTime at UTC, giving its timevalue.

Turns out something was different. When redeploying the code in one the environments, it started to show the "2021-01-02T07:00:00Z" like the other. My working theory is that for some reason one of the pods was set to UTC time, but now at MST time.
Also, the whole one entry being out of order was due to it not having Sort by function, and when I inserted all of these in Oracle, I forgot the first entry and it got put to the end.
¯\_(ツ)_/¯

Related

How do I convert between org.hibernate.type.TimestampType and Oracle SYSDATE?

I have a column that is mapped in hibernate using org.hibernate.type.TimestampType. How can I use native Oracle SQL to store and retrieve these values based on an Oracle TIMESTAMP?
The column is mapped as NUMBER(10). I tried using some formulas I found for Unix timestamps, but they did not seem to produce the correct results.
Here is a recent timestamp:
1579730473525
This would have been some date within the last 2-3 weeks (Jan 2020).
Details
I want to use Hibernate Envers, with the ValidityAuditStrategy. I'm running into trouble because I'm applying Envers to a database of existing records that have no audit history. What I'm trying to do is do a one-time insert of audit data, using Oracle SYSDATE as the timestamp.
I wasn't sure what format your number 1579730473525 was in, so I took a guess and took the first 10 digits using a SUBSTR, and the result was a reasonable 2020 date as follows.
SELECT TO_DATE('1970-01-01','YYYY-MM-DD') +
NUMTODSINTERVAL(TO_NUMBER(SUBSTR('1579730473525',1,10)), 'SECOND') FROM dual;
returns
22/01/2020 22:01:13
Then to get the TIMESTAMP, I added the last 4 digits.
SELECT to_char(TO_DATE('1970-01-01','YYYY-MM-DD') +
NUMTODSINTERVAL(TO_NUMBER(SUBSTR('1579730473525',1,10)), 'SECOND') ,'YYYY-MM-DD hh:mm:ss') ||'.'||SUBSTR('1579730473525',10,4)
FROM dual;
and this returns:
2020-01-22 10:01:13.3525
(I couldn't find a way of directly converting the 14 digit number back to a YYYY-MM-DD hh:mm:ss:ff format; it complained of precision)
Then to get the number into TIMESTAMP format:
SELECT TO_TIMESTAMP(TO_CHAR(TO_DATE('1970-01-01','YYYY-MM-DD') +
NUMTODSINTERVAL(TO_NUMBER(SUBSTR('1579730473525',1,10)), 'SECOND') ,'YYYY-MM-DD hh:mi:ss') ||'.'||SUBSTR('1579730473525',10,4),'YYYY-MM-DD hh:mi:ss:ff')
FROM dual;
and this returns it in the Oracle TIMESTAMP as requested, using Oracle SQL.
Just a hint: if you leave out formatting, make a note of your NLS parameter NLS_TIMESTAMP_FORMAT in case you get formatting issues.

How to change time zone in xml audit file (Oracle 11g)?

i'm working on a project in java to display everything what happend in my Oracle 11g Database. For this i started using the Audit Trail in XML format because i want to use it in my network.
I created a user for example to try this out. But my Problem is the wrong timestamp in the xml files and i would need it to check the time of connections etc.
<?xml version="1.0" encoding="UTF-8"?>
<Audit xmlns="http://xmlns.oracle.com/oracleas/schema/dbserver_audittrail- 11_2.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/oracleas/schema/dbserver_audittrail-11_2.xsd">
<Version>11.2</Version>
<AuditRecord><Audit_Type>1</Audit_Type><Session_Id>1260546</Session_Id><StatementId>1</StatementId><EntryId>1</EntryId><Extended_Timestamp>2016-10-01T15:59:47.473000Z</Extended_Timestamp><DB_User>CC</DB_User><OS_User>Admin-PC\Admin</OS_User><Userhost>WORKGROUP\ADMIN-PC</Userhost><OS_Process>1780:2512</OS_Process><Terminal>ADMIN-PC</Terminal><Instance_Number>0</Instance_Number><Action>100</Action><TransactionId>0000000000000000</TransactionId><Returncode>0</Returncode><Comment_Text>Authenticated by: DATABASE</Comment_Text><Priv_Used>5</Priv_Used><DBID>1434098587</DBID>
</AuditRecord>
<AuditRecord><Audit_Type>1</Audit_Type><Session_Id>1260546</Session_Id><EntryId>2</EntryId><Extended_Timestamp>2016-10-01T15:59:50.798000Z</Extended_Timestamp><DB_User>CC</DB_User><OS_User>Admin-PC\Admin</OS_User><Userhost>WORKGROUP\ADMIN-PC</Userhost><Terminal>ADMIN-PC</Terminal><Instance_Number>0</Instance_Number><Action>101</Action><Returncode>0</Returncode><DBID>1434098587</DBID>
</AuditRecord>
</Audit>
The Timestamp here is set at 15:59 but in my timezone it should be 17:59 (UTC+01:00). Then i tried this statement to check the timezone and curiously it was the right time.
SELECT db_user, extended_timestamp, action FROM v$xml_audit_trail WHERE db_user='CC' ORDER BY extended_timestamp DESC;
DB_USER EXTENDED_TIMESTAMP ACTION
CC 01.10.16 17:59:50,798000 +02:00 101
Do anyone know how to set the right timezone for the xml format?
Thanks in advance!
According to the documentation:
Extended_Timestamp indicates the time of the audited operation (timestamp of user login for entries created by AUDIT SESSION), in Coordinated Universal Time (UTC) or Greenwich Mean Time (GMT). This field only appears in the XML audit files, not the OS text audit files.
There doesn't seem to be anyway to change that, unless you transform the XML in the file later.
The timestamp is correct, it's just always in UTC. Whatever is going to consume this XML (you said you want to use it 'in your network') should be able to recognise that, and convert to other time zones if needed, but doing everything in UTC can be simpler anyway.
As an alternative you could generate your own XML from the v$xml_audit table with the data in whatever format(and timezone) you want, using the built-in XML generation tools (such as dbms_xmlgen).

Query using setDate does not find results - cannot see final-query with parameters

I have an SQL which looks into a dimension table (which stores every dates until year 2020) and then shall retrieve the todays row.
I watched into the table, todays date is in there.
The problem is, that SQL does not return any result.
I am thinking of a problem related to the use of java.sql.PreparedStatement.setDate method.
In past i think this was working fine, now I did some kine of regression test and it failed. The differences to the past are having Oracle 12 DB now instead of 11 in past and running it on CentOS 6.5 instead of AIX.
On search I found this topic here:
Using setDate in PreparedStatement
As far as I can see, I am doing as suggested.
Heres the java code and the query:
public static String SELECT_DATUM = "SELECT TIME_ID, DATE, DAY_NAME, WEEK_NAME, MONTH_NAME, YEAR_NAME, SORTING, RELATIONDATE, VALID_TO, VALID_FROM FROM DIM_TIME WHERE DATE = :date";
java.util.Calendar now = Calendar.getInstance();
now.clear(Calendar.HOUR);
now.clear(Calendar.MINUTE);
now.clear(Calendar.SECOND);
now.clear(Calendar.MILLISECOND);
Date tmpDate = now.getTime();
Date tmpDate2 = new Date(((java.util.Date)tmpDate ).getTime());
statement.setDate(1, tmpDate2 );
I notice that getTime() is called twice. But I dont think its that bad.
I also noticed some displaying formats:
in Database the date-colums shows me the date like this: '08.11.2015'
in java while debugging tmpDate2 shows me a date like this: '2015-11-08'
in java while debugging tmpDate shows me a date like this 'Sun Nov 08 12:00:00 CET 2015'
But again, these are just display formattings while it is a dateobject in background and a date-type in database. I would expect that je JDBC driver would map this itself without formattings, that why we are using setDate method and not setString.
What am I doing wrong? What could I do for further debugging to get it?
I would like see the resulting SQL query which is finally executed with the parameter.
I tried this sql on db isntance:
SELECT * FROM v$sql s WHERE s.sql_text LIKE '%select time%' ;
but only getting this then: "... where date = trunc(:1 )"
On this row at least I can see that it was using the right schema I expected it to use and where I checked whether todays date is available.
Edit:
something I found out:
I saw another code using the same function but giving an GregorianCalendar instead Calendar. When using
new GregorienCalandar();
instead of
Calendar.getInstance();
Theres no difference.
But when I assign a date and dont let the system take the current time, then it works:
Using
new GregorianCalendar(2015, Calendar.NOVEMBER, 8);
Would retrieve the row I want from SQL.
Zsigmond Lőrinczy posted this answer as comment:
Try this: SELECT TIME_ID, DATE, DAY_NAME, WEEK_NAME, MONTH_NAME,
YEAR_NAME, SORTING, RELATIONDATE, VALID_TO, VALID_FROM FROM DIM_TIME
WHERE DATE = TRUNC (:date) – 3 hours ago
This works for my problem.
I am writing this as reponse to check it later as answer on this question if hes not going to write his own response (to get the reputation-points).
But I am wondering how I could get the same by preparing on java.
The code uses the clear-methods, which where released into an own method named 'trunc'. I think the programmer intendet to do this instead of TRUNC in SQL. I am wondering if it werent possible to do so in java and if yes, how?
Edit:
And I am wondering why a TRUNC is needed at all. Because the column in Database is of type Date an not Timestampt. So wouldnt there be an automatically trunc? I would expect this. Why do I need a trunc on SQL?

JPA + PostgreSQL: Only time being persisted

I have a PostgreSQL table containing a timestamp without time zone field. This is configured in my Java code as follows:
#Column(name = "timestamp")
#Temporal(TemporalType.TIMESTAMP)
private java.util.Date timestamp;
The timestamp property is being set to new Date() i.e. containing both the date and the time. However in the database the date part is not being persisted e.g. "14:40:28.889"; therefore when it is retrieved from the database the date is not loaded and set to default i.e. 01/01/1970. Any ideas where the date part of the timestamp is running off to?
UPDATE:
I increased the logging level for hibernate so I can see what is being persisted by adding the following in the application.properties file:
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
The log output was as follows:
binding parameter [6] as [TIMESTAMP] - [Wed Sep 16 08:57:03 CEST 2015]
UPDATE 2:
I stepped through the code and found the insert sql with the date formatted as 2015-09-16 11:16:09.416000 +02:00:00. I insert the string automatically in PGAdmin and it insert with no error. After save a clicked the little refresh button and the date part disappeared! So the data is being persisted correctly but somehow postgre is doing something weird afterwards.
This was one of the silliest mistakes ever, I had a script that creates the tables and it was marked as "time without timezone" i.e. not timestamp so PostgreSQL was obviously removing the date. I will leave this question as it might help someone debug similar issues.

Oracle Date Literal [DD-MON-RR HH.MI.SSXFF AM]

I'm trying to use the timestamp format [DD-MON-RR HH.MI.SSXFF AM] to insert my date.
I can't modify the database settings in anyway possible, and I have to insert the date through a JAVA's string format (I can't modify the class that defined it either).
Having said that, I need to literally reconstruct the format string-by-string without tempering the other class/db.
The nls settings for date is DD-MON-RR. 12-JUN-2012 and 12/JUN/2012 worked perfectly fine.
But I find it difficult to recreate the timestamp part of the date.
Listed below is a few format I've tried.
'12-JAN-12' < success
'12/JAN/2012' < success
'12/JAN/2012 10.30.25.000 AM < failed
'12/JAN/2012 10:30:25.000 AM < failed
Did messed up the : or .? Or was the zero(s) aren't enough for miliseconds? Been in this trouble for hours now.
Thanks in advance.
EDIT
After a few reasoning sessions, the seniors gave their permission to alter the model class. Everything's good now. Thanks for the help and suggestions.
Since you must send a string to the DB, you must rely on the implicit conversion of the oracle DB to the DATE type.
Since you can't change the DB settings, the only thing I can suggest is changing the session settings.
So, if you can run commands against the DB, try:
Statement st = conn.createStatement();
st.execute("alter session set NLS_DATE_FORMAT='dd/mm/yyyy hh24:mi:ss'");
(or some other format (it's not recomended to use mon in your format because it might involve NLS_TERRITORY too))

Categories