Informix JDBC timestamp string format - jdbc

I have Informix database with timestamp field defined as YEAR TO SECOND.
When I show this field using JDBC rs.getString(column) it uses format with miliseconds so this field looks like:
2008-12-18 13:58:14.0
I would like it to use only YEAR TO SECOND fields. I set environment variable:
GL_DATETIME=%Y-%m-%D %H:%M:%S
but even then I got miliseconds. Programs using ODBC do not show milisecond. How can I receive TIMESTAMP string "YEAR TO SECOND" only? In my program I can check metadata if field is TIMESTAMP and then cut ".0", but I think there should be simplier way.
Server version:
IBM Informix Dynamic Server Version 11.50.TC2DE
Client version:
IBM Informix JDBC Driver for IBM Informix Dynamic Server 3.50.JC3DE
EDIT
It looks that all other JDBC drivers I tested (Oracle and PostgreSQL) shows Timestamp columns with miliseconds if I use getString(). So I used solution proposed by Todd. I check metatdata and if column is Timestamp then I use getTimestamp() and format it.

If you are using JDBC, you can use the rs.getDate(column) or rs.getTimestamp(column) methods, which return Date and Timestamp objects respectively. Then you have an object representing time, rather than a String expressing it directly. With Date or Timestamp, you can use a date formatter to format it to whatever String representation of that time you choose.
Update (after reading comments below):
If you use getDate(), it will still work for Timestamp columns. It will just reduce the precision down to the second. That way you don't have to check the metadata, you just have to know that the column is some kind of timestamp or date.

Related

Changing format of date without using to_char - Oracle

I have to get the max payment date on an invoice and I am having trouble with the date format. I do not need the max in this formula as I am using the format in a reporting tool that is pulling the max from what it finds for me.
Using "to_char({datefield},'mm/dd/yyyy')" works for displaying that date the way we would like BUT when you use summary function MAX it does not pull the correct date because it is looking at a string and not a date (it will think 12/3/21 is larger than 3/2/22).
Another thing I have tried is trunc - "trunc({datefield})" which gives us the correct max date but it changes the formatting. For example if the date prior to the formula being applied is "8/12/21 12:00:00:000" the trunc formula will display it as 12-08-21 which is horribly wrong.
Long story short is I need a way to change a date/time to date with the format of 'mmmm/dd/yyyy' WITHOUT converting it to a string with something like to_char. Thank you!!!!
A DATE is a binary data type consisting of 7 bytes representing: century, year-of-century, month, day, hour, minute and second. It ALWAYS has all of those components and it is NEVER stored with any (human-readable) format.
What you are seeing when a date is displayed is the client application you are using to access the database making a decision to be helpful to you, the user, and display the binary DATE provided by the database in a human-readable format.
If you want to change how the DATE is displayed then you either need to:
Change the settings on the client application that controls how it formats dates when it displays them to you; or
Change the data-type so that it is no longer a DATE (which does not have a format) to a data type where the values of the date can be formatted (such as a string). You can do this using TO_CHAR.
If you want to find the maximum then do it BEFORE applying the formatting:
SELECT TO_CHAR(MAX({datefield}),'mm/dd/yyyy')
FROM your_table;

Storing unix timestamp versus string with UTC

I have a conversation today with my engineering coworkers about application and database design in Fintech.
How do we handle time? We all know that we need to store the datetime information normalized in UTC. But our debate is among whether we should store in 1) unix epoch timestamp which is an integer in our database, for example, 1596507157. which is 08/04/2020 # 2:12am UTC or 2) store in ISO 8601 format in string 2020-08-04T02:12:37+00:00 or 2020-08-04T02:12:37.123456789Z
The downside of unix timestamp is obviously not immediate human-readable.
I am here looking for some design advices on whether we should adopt either approach.
In my opinion, you should store it as integer rather than string, one of many reasons is obvious, int just needs 4 byte while string as ISO 8601 takes a lot more.
What you see as downside, it doesn't impact the backend, it's just a make up (only needed on user view).
Most of database have datetime data type. I guess your 'epoch timestamp' means this datetime or timestamp data type. It's easier (and better performance) to handle datetime type for database engineer. and database also have datetime formatting function.
(Oracle/MS SQL Server - convert, MySQL - date_format, PostgreSQL - to_char ...)
In my opinion, store and handle with datetime type and use formatting function for human.

hibernate JDBC type not found

Does hibernate have any mapping for this oracle data type:(10G)
TIMESTAMP(6) WITH TIME ZONE
I am getting:
No Dialect mapping for JDBC type: -101
My manager does not want to do the: registerHibernateType(-101, Hibernate.getText().getname())
He thinks it is too much.:)
What alternative can I have?
The answer you provide to yourself is more like a workaround than a proper solution. For the sake of the visitors looking for an answer, I'll provide my view on this:
1) Database date-based fields should be always set to UTC, never with a specific timezone. Date calculation with timezone information is an unneeded complexity. Remember that timezones usually changes twice a year for a lot of countries in the world ("daylight saving time"). There's a reason why only a few RDMBS' supports this, and there's a reason why Hibernate developers refuse to support this data-type. The patch for Hibernate is simple enough (one line of code), the implications aren't.
2) Converting your "timestamp with timezone" to a String will only cause problems later. Once you retrieve it as String, you'll need to convert it again to a Date/Calendar object, an unneeded overhead. Not to mention the risks associated with this operation.
3) If you need to know in which timezone is some user, just store the String representing the timezone offset (like "Europe/Prague"). You can use this in Java to build a Calendar with date/time and timezone, as it'll take care of DST for you.
For now, I solved the problem by:
`select TO_CHAR(TRUNC(field)) from table` //field is the one having type= timestamp with timezone
This ensures that when the query returns, the field has datatype 'String'

Oracle - Fetch date/time in milliseconds from DATE datatype field

I have last_update_date column defined as DATE field
I want to get time in milliseconds.
Currently I have:
TO_CHAR(last_update_date,'YYYY-DD-MM hh:mi:ss am')
But I want to get milliseconds as well.
I googled a bit and think DATE fields will not have milliseconds. only TIMESTAMP fields will.
Is there any way to get milliseconds? I do not have option to change data type for the field.
DATE fields on Oracle only store the data down to a second so there is no way to provide anything more precise than that. If you want more precision, you must use another type such as TIMESTAMP.
Here is a link to another SO question regarding Oracle date and time precision.
As RC says, the DATE type only supports a granularity down to the second.
If converting to TIMESTAMP is truly not an option then how about the addition of another numerical column that just holds the milliseconds?
This option would be more cumbersome to deal with than a TIMESTAMP column but it could be workable if converting the type is not possible.
In a similar situation where I couldn't change the fields in a table, (Couldn't afford to 'break' third party software,) but needed sub-second precision, I added a 1:1 supplemental table, and an after insert trigger on the original table to post the timestamp into the supplemental table.
If you only need to know the ORDER of records being added within the same second, you could do the same thing, only using a sequence as a data source for the supplemental field.

Storing Dates in Oracle via Hibernate

I'm storing a simple java.util.date in an Oracle XE database via hibernate.
When testing with JUnit if I can retrieve the correct value, I get an error like this:
junit.framework.AssertionFailedError:
expected:<Sun Dec 28 11:20:27 CET 2008>
but was:<2008-12-28 11:20:27.0>
The value is stored in an Oracle Date column (which should have a second-precision) which looks okay to me. Also, I'm surprised that 11:20:27 is not equal to 11:20:27.0. Or does this have to do with timezones?
Any help is welcome.
Thorsten
Okay, worked some more on it ...
Oracle Date columns only store values with an accuracy of a second.
Java Dates do contain milliseconds, but they are typically not printed. So
expected:
was actually created by a date like 11:20:27,345, which is of course not equal to 11:20:27.0
Solution:
either only use full second dates to store and retrieve
or
get hibernate to create the correct Oracle Datatype (TIMESTAMP) - this is very dependent on the dialect specified in the hibernate config (OracleDialect and Oracle10gDialect create different types).
If you compare a java.util.Date to a java.sql.Date that both represent the same instant in time, equals(Object) will return false (it considers two objects of different classes to never be equal).
Your tests need to account for that. The easiest way to do this is to convert the dates to UNIX time (e.g. java.util.Date.getTime()) and compare those values.

Resources