DB2/IDAA: How to properly format VARCHAR to TIMESTAMP with milliseconds - database

I am using IDAA for DB2. At one point I use TO_DATE to convert some dates and it works:
TO_DATE('09/03/2018 06:49:23','MM/DD/YYYY HH:MI:SS')
But when I have a VARCHAR value with milliseconds in the timestamp, TO_DATE returns an error. I looked around online and found an answer that says to use TO_TIMESTAMP but that doesn't work:
TO_TIMESTAMP('09/03/2018 06:49:23.443000','MM/DD/YYYY HH:MI:SS.NNNNNN')
I've looked at every answer on here and tried many variations. I've tried every combination of the functions TO_TIMESTAMP, TO_DATE, TIMESTAMP_FORMAT and the format for milliseconds as FF, FF6, NNNNNN. I get these errors:
NO AUTHORIZED FUNCTION NAMED TO_TIMESTAMP HAVING COMPATIBLE ARGUMENTS WAS FOUND. SQLCODE=-440
SQL error: SQLCODE = -904, SQLSTATE = 57011, SQLERRMC = Invalid Date.. SQLCODE=-904
Maybe it's different for the IDAA? I don't know.
I'm running DB2 for z/OS V11 using IBM Data Studio 4.1.3.

TIMESTAMP_FORMAT for Db2 for z/OS is documented here
https://www.ibm.com/support/knowledgecenter/en/SSEPEK_12.0.0/sqlref/src/tpc/db2z_bif_timestampformat.html
Do note that HH is the same as HH12, not HH24, so it might be that you need, e.g.
$ db2 "values TIMESTAMP_FORMAT('09/03/2018 16:49:23','MM/DD/YYYY HH24:MI:SS')"
1
--------------------------
2018-09-03-16.49.23.000000
1 record(s) selected.
( The above is from Db2 LUW, but I would assume that function works the same on Db2 for z/OS/ and DAA )

Based on the following link -
https://www.ibm.com/support/knowledgecenter/en/SS4LQ8_4.1.0/com.ibm.datatools.aqt.doc/gui/concepts/c_idaa_inconsistencies.html
IBM Db2 Analytics Accelerator for z/OS does not support all date and time formats that Db2 supports. This might lead to different results for accelerated and inhouse Db2 queries if the VARCHAR_FORMAT or TIMESTAMP_FORMAT scalar function is used. The following formats are not supported by IBM Db2 Analytics Accelerator for z/OS:
FF[n] - fractional seconds (000000-999999)
The optional number n is used to specify the number of digits to include in the return value. Valid values for n are the integers from 1-6. The default is 6.
ID - ISO day of the week (1-7)
The value 1 represents Monday. The value 7 represents Sunday.
IYYY - ISO year (0000-9999)
The last four digits of the year based on the ISO week that is returned.
NNNNNN - microseconds (000000-999999)
This format is equivalent to FF6.
RR - last two digits of the year (00-99)
SSSSS - seconds since the previous midnight

Related

In PostgreSQL timezone offset is taken with the wrong sign

I'm experimenting with PostgreSQL TIME datatype and I notice a strange behavior.
test=# SELECT CURRENT_TIME;
current_time
--------------------
08:43:35.446737+00
(1 row)
test=# SELECT CURRENT_TIME AT TIME ZONE '+04';
timezone
--------------------
04:43:50.475164-04
(1 row)
test=# SELECT CURRENT_TIME AT TIME ZONE '-04';
timezone
--------------------
12:43:54.810124+04
(1 row)
As you can notice, the default timezone is 00, so when I convert it +04, I expect to get the result that I get when converting it with -04
Is anyone familiar with the reasons behind this behavior or this is a bug
You are using POSIX style time zone names, which work a bit strangely. From the docs:
Another issue to keep in mind is that in POSIX time zone names, positive offsets are used for locations west of Greenwich. Everywhere else, PostgreSQL follows the ISO-8601 convention that positive timezone offsets are east of Greenwich.
Also, from the same docs:
We do not recommend using the type time with time zone (though it is supported by PostgreSQL for legacy applications and for compliance with the SQL standard).

CONVERT vs CAST when exporting datetime as dates from sql server

I help out a collegue with exporting data from SQL Server 2012. I type manual queries and then copy/paste the results to an Excel sheet that I then share with him. The extract I make will be an excel file that will be manually analysed. No need for automation.
What I try to do is settling for best practice when exporting order statistics grouped by day, trying to learn SQL better. I have a field of type datetime, and I want to convert this to some date format. In my locale, the typical date format is YYYY-MM-DD. I do sometimes share my script with others, that might have another locale. I have found three statements that seem to yield the same values for me.
select top 1
createdat
, CAST(createdat as date) as A
, CONVERT(char(10), createdat,126) as B
, CONVERT(char(10), createdat,127) as C
from dbo.[Order]
resulting in
createdat |A |B |C
2012-12-27 08:23:32.397 |2012-12-27 |2012-12-27 |2012-12-27
From the TSQL MSDN reference (link) I understand that:
A is handled by SQL as type Date, whereas B and C are chars.
B and C should differ by their time zone handling.
But I dont understand:
HOW does B and C handle time zones?
What is the practical difference when copy/pasting to Excel?
Is there practical difference if I share this script with collegues using another locale I should consider?
Should one or the other be preferred?
To answer your questions sequentially:
126 uses the ISO 8601 date standard, which signifies the Year aspect to be the full 4 characters long, rather than just the last two. 127 uses the same date standard, but in Time Zone Zulu, which is a military time zone (4 hours ahead of EST)
There essentially is no difference when copy/pasting to Excel. When opening an Excel doc, the default cell formatting is "General". When you paste any of these date types into Excel, it will register option A as a number (in this case 41270) and based on the pre-existing format from your query will convert it to Date format. Options B and C will first register as text, but since they are in the format of a Date (i.e. they have the "/" marks), Excel can register these as dates as well and change the formatting accordingly.
As long as the person you are sharing your script with uses T-SQL this shouldn't cause problems. MySQL or other variations could start to cause issues.
CAST(createdat as date) is the best option (IMO)
Sources:
SQL Conversion Types
ISO 8601 Details
Zulu Time Zone

Time in UTC HEX format. How to convert to normal time?

I have some application for dataaquistion from 3rd party developer company. The timestamps are saved by the app to a unknown format. The column in the MSSQL 2008 database is named "UTC" and datatype is varchar(32).
Timestamp sample:
2455832.07550638:000000A9
2455832.07552953:00000173
2455832.07555267:0000023B
2455832.07557582:00000303
Is anybody know how to convert via MSSQL query ?
I don't know about MSSQL, but your timestamp format (the part to the left of the colon) looks like Julian dates: the number of (fractional) days elapsed since noon, Jan 1, 4713 BC (UT). From the number of decimal digits, the time resolution seems to be about one millisecond. You can convert Julian dates to a Unix timestamp simply by unix_timestamp = (jd-2440587.5)*86400. I don't get the meaning of the second field (the hexadecimal part), but I guess it's not part of the timestamp.

Independent format for a string representation of date/time value, for MS SQL server?

I have a question about MS SQL Server string-to-datetime implicit conversion.
Specifically, can I be sure that a string in the 'yyyy-mm-dd hh:mm:ss' (e.g '2011-04-28 13:01:45') format, inserted into the datetime column, will always be automatically converted to a datetime type, no matter what regional or language settings are used on the server?
If no, does there exist such an independent string format for date time?
Does it depend on MSSQL server version and how?
thank you in advance
No.
If you're using a datetime column (as opposed to the newer types introduced in 2008), the safe format includes the letter T between the date and time components, e.g. '2011-04-28T13:01:45'.
For an ambiguous date (where the day <= 12), SQL Server can confuse day and month:
set language british
select MONTH(CONVERT(datetime,'2011-04-05 13:01:45'))
----
5
set language british
select MONTH(CONVERT(datetime,'2011-04-05T13:01:45'))
----
4
More generally, however, you should find a way to avoid treating datetime values as strings in the first place, e.g. if you're passing this value from some other (non-SQL) code, then use whatever facilities are available in your data access library (e.g. ADO.Net) to pass the value across as a datetime value - let the library deal with any necessary translations.

Saving Dates in SQLServer

I have a legacy application where the input is a date string, i.e.:
06/12/2009
The format of the input is always a string, and is consistent, it's always dd/mm/yyyy
At the moment the legacy app just INSERTS this in a DateTime fields. Obviously if the Localization Culture settings of the Server change, we have a bug.
Two questions:
One:
Whats the safest way to store Dates in SQLServer in this situation?
Is there a format that will always be correctly interpreted regardless of the order of day and month?
Two:
What settings exactly determines the culture of a SQLServer DB, is it an OS setting, or a setting of that DB, or what?
cheers
Format YYYY-MM-DD is unambiguous, meaning that SQL Server won't confuse the month
and day when converting a string value to DATETIME. (I've never experienced a problem with an implicit conversion using that format using the four digit year.)
The "safest" (and most convenient) way to store date values in SQL Server is to use DATETIME datatype.
Use the CONVERT function to explicitly specify the input and output formats when converting between DATETIME and strings.
SQL Server 2005 Documentation on CONVERT style argument values:
http://msdn.microsoft.com/en-us/library/ms187928(SQL.90).aspx
To convert a string representation to DATETIME datatype:
select CONVERT(datetime, '2009-06-03', 20)
The first argument is datatype to convert to, the second argument is the expression to be converted, the third argument is the style.
(style 20 is ODBC Canonical format = 'YYYY-MM-DD HH:MI:SS' (24 hour clock)
[FOLLOWUP]
To convert a DATETIME expression (e.g. getdate() to VARCHAR in 'YYYY-MM-DD' format:
select CONVERT(varchar(10), getdate(), 20)
Note that specifying varchar(10) gets you just the first 10 characters of the etnire 'YYYY-MM-DD HH:MM:SS' format.
[/FOLLOWUP]
As to what determines the default formats, that's going to be research. We avoid the issues caused by default formats by specifying the formats.
I would recommend storing all dates in UTC time when they are placed into the database. It will be consistent that way.
Storing dates like this seems to work well...
YYYY-MM-DD
See SET DATEFORMAT. The SQL 'culture' is set by SET LANGUAGE at a session level. SQL Server has its own date format settings, independent of the hosting OS. This is for several reasons: ANSI compliance, to prevent OS changes from affecting applications using the database hosted on that host and not least is compatibility, the SQL long predates the OS is currently running on.
Keep in mind that DATA is not its PRESENTATION. In this case that DATA is a DATE or DATETIME, regardless of how you show them.
As for inserting/updating/comparing datetime values, I quote the BOL:
When specifying dates in comparisons
or for input to INSERT or UPDATE
statements, use constants that are
interpreted the same for all language
settings: ADO, OLE DB, and ODBC
applications should use the ODBC
timestamp, date, and time escape
clauses of:
{ ts 'yyyy-mm-dd
hh:mm:ss[.fff] '} such as: { ts
'1998-09-24 10:02:20' }
{ d 'yyyy-mm-dd'} such as: { d '1998-09-24' }
{ t 'hh:mm:ss'} such as: { t '10:02:20'}
I can assure you that, if you use this formats they will always work, regardless of the locale of you server
I'm a bit conservative in these matters, but I prefer to use separate Year / Month / Day fields in the table, rather than a Date field that uses a DBMS-specific data type. It certainly takes more space, but the lack of ambiguity and increased portability is worth it to me.
The price you pay is that you don't get free date/time arithmetic and sorting, but it's easy enough to do yourself or by a slightly more complex "ORDER BY" clause.
I agree with the advice from spencer7593, but please be aware that using cast or convert without a format can give unexpected results. This T-SQL query returns 12, not 1.
set language British
select month(CAST('2016-01-12' AS datetime))
Normally I prefer to insert as
insert into tbl values('yyyyMMdd')
Then, itll be inserted in proper format based on db.

Resources