Vertx Oracle Datetime in LocalTime - vert.x

Version
Vertx 4.3.4, JDBCClient
Questions
Our Oracle-database is setup in the local-timezone "Europe/Vienna" and returns the local-time over JDBC. But within the convertion of the VertX-JDBC the time markt in any case to UTC.
If you do a
pool.preparedQuery("select SESSIONTIMEZONE as sessionTimeZone, sysdate as dateValue, to_char(sysdate,'yyyy-dd-mm hh24:mi:ss') localTime from dual")
The output will be:
"sessionTimeZone":"Europe/Vienna",
"dateValue":"2022-10-17T10:06:45Z",
"localTime":"2022-17-10 10:06:45"
I assume it is related to this code-part (JDBCDecoderImpl.java, Line 188), where the returned timestamp is set hard-coded to UTC:
if (descriptor.jdbcType() == JDBCType.TIMESTAMP || descriptor.jdbcType() == JDBCType.TIMESTAMP_WITH_TIMEZONE) {
return LocalDateTime.parse(value.toString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME).atOffset(ZoneOffset.UTC);
}
The oracle-jdbc-driver always return the timestamp in the timezone the database is setup. There is no possibility as it is at MySQL, where the timezone could be defined.
Is there a way to workaround this conversion?

This is a known issue from JDBC with Oracle Databases. In order to correctly set the timezone (without requiring any code changes) you can issue the following statement at start of each connection:
ALTER SESSION SET TIME_ZONE = 'UTC'
This will allow you to set the timezone for the session which should match the application. In this case, UTC.
There are other options too. For example if you can modify the database you can set the database timezone at creation time:
CREATE DATABASE myDB
...
SET TIME_ZONE='UTC';
Or modify it after creation:
ALTER DATABASE myExistingDB
...
SET TIME_ZONE='UTC';
If you don't want/can alter the database and want to keep using the vert.x client without managing the connection yourself, in other words, keep using 1 shot queries, you can specify at the query level the timezone too:
SELECT
FROM_TZ(TIMESTAMP '2030-01-01 12:30:35', '-04:00')
AT TIME ZONE '+12:00'
FROM DUAL;

Related

Postgres Running in Docker Container: Change current time, now() to custom date time

I have a postgres timescale database running in docker. For the purposes of api testing I want SELECT NOW() to return lets say 2010-12-01 23:00:44.851242 +00:00. Basically every time I start up the container I want it to think the current date is some time in December 2010.
How can I achieve this? I cant seem to find any command to set current time in postgres. Do I need to change the system time in the docker container before the database shows up? Is that even something I can do?
You can achieve this by creating a custom now() function in a separate schema and then adjusting the search_path to prefer that function over the builtin now function:
CREATE SCHEMA test;
CREATE OR REPLACE FUNCTION test.now() RETURNS timestamptz LANGUAGE SQL AS $$ SELECT '2000-01-01 0:00'::timestamptz; $$;
SET search_path TO test,pg_catalog,public;
-- make search_path change permanent for a specific user
ALTER USER <testuser> SET search_path TO test,pg_catalog,public;
SELECT now();
now
------------------------
2000-01-01 00:00:00+01
(1 row)
Time: 1.826 ms

Swapping Timestamp for Timestamp With Time zone causes error with jdbc

I'm looking for a way around an unexpected problem. We have a third party app that is loading data into our database. It's our code that creates the postgresql schema, the third party doesn't provide it. With TIMESTAMP columns this works, but we'd much prefer to use TIMESTAMP WITH TIME ZONE.
We tried to do this by changing the default TimeZone of the user. The following SQL works through psql. The fixed timezone for the user is assumed:
insert into AAA (FOO,BAR) select 'X','2022/03/19 21:15:25' where not exists (select 1 from AAA where FOO = 'X'
But the app is raising an exception:
Caused by: org.postgresql.util.PSQLException: ERROR: column "BAR" is of type timestamp with time zone but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
The timezone of the user was set with:
insert into pg_db_role_setting (setrole, setdatabase, setconfig) values (16394, 0, '{TimeZone=+10}')
And in psql, subsiquent calls to SELECT now() return in +10 timezone as desired.
Firstly, why could JDBC be hitting an error when the psql doesn't on the same insert statement?
Secondly is there any workaround for this without changing the program source code?

LAMBDA current_timestamp towards Postgres

Question is very simple:
We are executing select current_timestamp from lambda to PostgreSQL aurora (which is set to america/New_york timezone).
Scenario:
When we execute select Current_timestamp directly in PostgreSQL Server, it is giving the time in EST.
But when we execute the same form Lambda, it is giving UTC time zone.
I know that Lambda timezone is UTC.
But I am confused here, because am picking up this piece of code "select Current_timestamp" from dynamoDB and passing it as a string through lambda towards PostgreSQL. And I can see this statement is exciting in PostgreSQL too. It should pick up the timezone of PostgreSQL. Not sure why it is picking Lambda.
Need to fix this and I need to execute this statement from Lambda and get the Current_timestamp of PostgreSQL(Not LAMBDA)
current_timestamp returns the timestamp formatted for the current session, which may be in UTC. You have a few options:
SELECT current_timestamp at time zone 'America/New_York'; This is the most explicit.
Start each session with SET TIME ZONE 'America/New_York';
ALTER USER youruser SET TIME ZONE 'America/New_York'; This will default the user to this time zone, but the client can still override this.

PG SQL 10 set default time zone to UTC

I need to change the database config to use UTC as the default for a PostgreSQL10 instance hosted on AWS RDS. I want it permanently changed at the database level and to never revert back to any other timezone no matter what.
I've tried running this, but it shows 0 updated rows:
ALTER DATABASE <my-db> SET timezone='UTC';
I've tried attaching a custom param group to the DB in RDS and modifying the entries like so (also rebooted after):
No matter what I do, when I run select * from pg_settings where name = 'TimeZone'; or SHOW timezone it shows 'America/Chicago'.
It seems like this should be easy to do, but it is proving to be a challenge.
If you want to store your timestamps in UTC and always want the database to send the data to the client in UTC as well, you should use the data type timestamp without time zone, which will not perform any time zone handling for you. That would be the simplest solution.
To convert the data, you could proceed like this:
SET timezone = 'UTC';
ALTER TABLE mytable ALTER timestampcol TYPE timestamp without time zone;
Based on this dba.stackexchange.com question. Apparently PG stores the timestamp in UTC time but then converts it to the session time zone. From what I've gathered, since my timestamps don't include time zone information, I need to tell PG that the timezone being stored is UTC, and then convert that to whatever local time is needed, so something like this:
SELECT my_timestamp_in_utc AT TIME ZONE 'UTC' AT TIME ZONE 'America/Denver' as my_local_time
FROM my_table;
This is a little verbose, but I'll go with it for now.

Is there any equivallent function in postgres like systimestamp() of oracle

I'm working on a oracle to postgresql database migration project. I need to read operating system date and time from postgres. In oracle sysdate() returns system date time in date type data and systimestamp() returns timestamp type data whatever the time_zone variable set. But in postgres current_date() and current_timestamp() always give the result relative to the timezone variable set for that database.
Synchronizing the timezone variable (i.e. set timezone='utc') is one way, but I don't want my timezone variable to be changed.
All I want to get is the current date and time of my system (time zone may include or not) like in oracle. Any pl/pgsql would be helpful. Thanks
The data type TIMESTAMP WITH TIME ZONE is different in Oracle and PostgreSQL.
While Oracle stores the timestamp information along with the timestamp, PostgreSQL stores the timestamp in UTC and displays it in the currently set time zone (available with the SQL statement SHOW TimeZone).
So the functions return the same time in PostgreSQL and Oracle, but it is displayed in a different fashion. That should normally be no problem.
If you really need to store time zone information along with a timestamp, you'll have to use a separate field to store the time zone information. You can then use AT TIME ZONE to convert the timestamp to that time zone for display.