You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Oracle datetimetz incorrectly parsed due to disagreement between OraclePlatform->getDateTimeTzFormatString() and Oracle driver's InitializeSession#6469
Open
wayne530 opened this issue
Jul 15, 2024
· 0 comments
all versions >= 3.7.0 (I did not check prior versions)
Summary
This issue was documented in #2332 however simply because a workaround exists, I would not consider the issue "fixed" as everyone using datetimetz will encounter this issue when using Oracle and as a result, will have many corrupted datetimetz values that need to be corrected even after the workaround is discovered and applied. tl;dr This is a major issue with a relatively trivial fix so rather than rely on a workaround (which requires digging through your issues to find), how about just fixing it in all actively maintained version branches?
Current behaviour
Timestamps that have a negative offset from GMT, for example PST (UTC-8) or PDT (UTC-7) are incorrectly parsed as positive offsets from GMT. For example, datetimetz values with a -08:00 offset are stored in Oracle as +08:00.
How to reproduce
Reproducing this issue is quite straightforward. The Oracle InitializeSession middleware sets NLS_TIMESTAMP_TZ_FORMAT to YYYY-MM-DD HH24:MI:SS TZH:TZM:
while OraclePlatform->getDateTimeTzFormatString() uses:
public function getDateTimeTzFormatString(): string
{
return 'Y-m-d H:i:sP';
}
Thus, if I wish set set a datetimetz from the current datetime in my location at the time of this writing, which is 2024-07-15T11:16:00-07:00, I would take the DateTime instance and format it to a string using the format provided by OraclePlatform, or 2024-07-15 11:16:00-07:00.
Connect to an Oracle database using credentials that allow you to create tables and insert. Initialize the session as the Oracle middleware would:
ALTER SESSION SET NLS_DATE_FORMAT ='YYYY-MM-DD HH24:MI:SS' NLS_TIME_FORMAT ='HH24:MI:SS' NLS_TIMESTAMP_FORMAT ='YYYY-MM-DD HH24:MI:SS' NLS_TIMESTAMP_TZ_FORMAT ='YYYY-MM-DD HH24:MI:SS TZH:TZM' NLS_NUMERIC_CHARACTERS ='.,';
Create a table with a single column that is a TIMESTAMP WITH TIME ZONE type:
CREATETABLEtest (created_at TIMESTAMP WITH TIME ZONE);
Insert a row into the table and provide the string formatted datetimetz as OraclePlatform would provide:
INSERT INTO test (created_at) VALUES ('2024-07-15 11:16:00-07:00');
Now view the stored row:
SELECT*FROM test;
Expected output:
2024-07-15 11:16:00 -07:00
Actual output:
2024-07-15 11:16:00 +07:00
Expected behaviour
datetimetz values should be stored with the correct UTC offset. Hopefully this is not controversial.
The fix
The fix is quite straightforward. Make OraclePlatform->getDateTimeTzFormatString() and Oracle middleware's InitializeSession agree on a datetimetz format, whether that is with OR without a space. For example, leave OraclePlatform as is and simply update InitializeSession as follows:
Bug Report
Summary
This issue was documented in #2332 however simply because a workaround exists, I would not consider the issue "fixed" as everyone using
datetimetz
will encounter this issue when using Oracle and as a result, will have many corrupteddatetimetz
values that need to be corrected even after the workaround is discovered and applied. tl;dr This is a major issue with a relatively trivial fix so rather than rely on a workaround (which requires digging through your issues to find), how about just fixing it in all actively maintained version branches?Current behaviour
Timestamps that have a negative offset from GMT, for example PST (UTC-8) or PDT (UTC-7) are incorrectly parsed as positive offsets from GMT. For example,
datetimetz
values with a -08:00 offset are stored in Oracle as +08:00.How to reproduce
Reproducing this issue is quite straightforward. The Oracle
InitializeSession
middleware setsNLS_TIMESTAMP_TZ_FORMAT
toYYYY-MM-DD HH24:MI:SS TZH:TZM
:while
OraclePlatform
->getDateTimeTzFormatString()
uses:Thus, if I wish set set a
datetimetz
from the current datetime in my location at the time of this writing, which is2024-07-15T11:16:00-07:00
, I would take theDateTime
instance and format it to a string using the format provided byOraclePlatform
, or2024-07-15 11:16:00-07:00
.Connect to an Oracle database using credentials that allow you to create tables and insert. Initialize the session as the Oracle middleware would:
Create a table with a single column that is a
TIMESTAMP WITH TIME ZONE
type:Insert a row into the table and provide the string formatted
datetimetz
asOraclePlatform
would provide:Now view the stored row:
Expected output:
Actual output:
Expected behaviour
datetimetz
values should be stored with the correct UTC offset. Hopefully this is not controversial.The fix
The fix is quite straightforward. Make
OraclePlatform
->getDateTimeTzFormatString()
and Oracle middleware'sInitializeSession
agree on adatetimetz
format, whether that is with OR without a space. For example, leaveOraclePlatform
as is and simply updateInitializeSession
as follows:The text was updated successfully, but these errors were encountered: