Oracle strange behavior when grouping by a TIMESTAMP field when the values are on the daylight saving border
I have a strange behavior of Oracle DB with TIMESTAMP and daylight saving.
The following query produces different results when grouping by different columns and it is not clear why.
When grouping by my_date_ny_ts it returns two different rows and when by my_date_ny_ts_tz - the result is only one row (the right one for me).
Please note the values are for the 11/04/2018 00:00:00 -05:00 and 11/04/2018 00:00:00 -06:00 that are converted to the New_York timezone to 11-04-2018 01:00 and 02:00 EDT which are actually 01:00 EDT and 01:00 EST.
I understand why those values are different, but they should be equal after converting them to the TIMESTAMP without time zone data type (the my_date_ny_ts column), since this type doesn't contain any information about timezone and daylight saving status (see the tdz_ny_ts values). Only after I convert the values back to the TIMESTAMP WITH TIMEZONE type (the my_date_ny_ts_tz) they become equal.
I don't need a workaround (already have it), just wondering if this behavior is an Oracle bug or by misunderstanding:
select count(*), my_date_ny_ts_tz from (
SELECT
mydate, -- timestamp with timezone
to_char( mydate, 'TZD') as tdz, -- daylight savings flag - VALUES are NULL because timezone is an offset
mydate AT TIME ZONE 'America/New_York' AS mydate_ny, -- timestamp with timezone in EST timezone
to_char( mydate AT TIME ZONE 'America/New_York', 'TZD') as tdz_ny, --timestamp with timezone in EST timezone - daylight savings flag - RETURNS EDT FOR ONE EST FOR SECOND - RIGHT
cast(mydate AT TIME ZONE 'America/New_York' as timestamp) as my_date_ny_ts,--cast to timestamp without timezone - GROUP BY RETURNS TWO ROWS - BUG?
to_char( cast(mydate AT TIME ZONE 'America/New_York' as timestamp) , 'TZD') as tdz_ny_ts,--cast to timestamp without timezone - daylight savings flag - both values are null so why the group by on the prev field doesn't work?
cast(mydate AT TIME ZONE 'America/New_York' as timestamp) AT TIME ZONE 'America/New_York' as my_date_ny_ts_tz,--cast back to timestamp with timezone in EST timezone - NOW GROUP BY RETURNS ONE ROW
to_char( cast(mydate AT TIME ZONE 'America/New_York' as timestamp) AT TIME ZONE 'America/New_York', 'TZD') as tdz_ny_ts_tz--daylight savings flag of the prev field - both are EST - RIGHT
FROM
(
SELECT
to_timestamp_tz('11/04/2018 00:00:00 -05:00','mm/dd/yyyy hh24:mi:ss TZH:TZM') AS mydate
FROM
dual
UNION
SELECT
to_timestamp_tz('11/04/2018 00:00:00 -06:00','mm/dd/yyyy hh24:mi:ss TZH:TZM') AS mydate
FROM
dual
)
) group by my_date_ny_ts_tz
My version is the following, but it happens in 12c as well:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
"CORE 11.2.0.4.0 Production"
TNS for 64-bit Windows: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
Thanks
oracle timezone timestamp dst timestamp-with-timezone
add a comment |
I have a strange behavior of Oracle DB with TIMESTAMP and daylight saving.
The following query produces different results when grouping by different columns and it is not clear why.
When grouping by my_date_ny_ts it returns two different rows and when by my_date_ny_ts_tz - the result is only one row (the right one for me).
Please note the values are for the 11/04/2018 00:00:00 -05:00 and 11/04/2018 00:00:00 -06:00 that are converted to the New_York timezone to 11-04-2018 01:00 and 02:00 EDT which are actually 01:00 EDT and 01:00 EST.
I understand why those values are different, but they should be equal after converting them to the TIMESTAMP without time zone data type (the my_date_ny_ts column), since this type doesn't contain any information about timezone and daylight saving status (see the tdz_ny_ts values). Only after I convert the values back to the TIMESTAMP WITH TIMEZONE type (the my_date_ny_ts_tz) they become equal.
I don't need a workaround (already have it), just wondering if this behavior is an Oracle bug or by misunderstanding:
select count(*), my_date_ny_ts_tz from (
SELECT
mydate, -- timestamp with timezone
to_char( mydate, 'TZD') as tdz, -- daylight savings flag - VALUES are NULL because timezone is an offset
mydate AT TIME ZONE 'America/New_York' AS mydate_ny, -- timestamp with timezone in EST timezone
to_char( mydate AT TIME ZONE 'America/New_York', 'TZD') as tdz_ny, --timestamp with timezone in EST timezone - daylight savings flag - RETURNS EDT FOR ONE EST FOR SECOND - RIGHT
cast(mydate AT TIME ZONE 'America/New_York' as timestamp) as my_date_ny_ts,--cast to timestamp without timezone - GROUP BY RETURNS TWO ROWS - BUG?
to_char( cast(mydate AT TIME ZONE 'America/New_York' as timestamp) , 'TZD') as tdz_ny_ts,--cast to timestamp without timezone - daylight savings flag - both values are null so why the group by on the prev field doesn't work?
cast(mydate AT TIME ZONE 'America/New_York' as timestamp) AT TIME ZONE 'America/New_York' as my_date_ny_ts_tz,--cast back to timestamp with timezone in EST timezone - NOW GROUP BY RETURNS ONE ROW
to_char( cast(mydate AT TIME ZONE 'America/New_York' as timestamp) AT TIME ZONE 'America/New_York', 'TZD') as tdz_ny_ts_tz--daylight savings flag of the prev field - both are EST - RIGHT
FROM
(
SELECT
to_timestamp_tz('11/04/2018 00:00:00 -05:00','mm/dd/yyyy hh24:mi:ss TZH:TZM') AS mydate
FROM
dual
UNION
SELECT
to_timestamp_tz('11/04/2018 00:00:00 -06:00','mm/dd/yyyy hh24:mi:ss TZH:TZM') AS mydate
FROM
dual
)
) group by my_date_ny_ts_tz
My version is the following, but it happens in 12c as well:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
"CORE 11.2.0.4.0 Production"
TNS for 64-bit Windows: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
Thanks
oracle timezone timestamp dst timestamp-with-timezone
add a comment |
I have a strange behavior of Oracle DB with TIMESTAMP and daylight saving.
The following query produces different results when grouping by different columns and it is not clear why.
When grouping by my_date_ny_ts it returns two different rows and when by my_date_ny_ts_tz - the result is only one row (the right one for me).
Please note the values are for the 11/04/2018 00:00:00 -05:00 and 11/04/2018 00:00:00 -06:00 that are converted to the New_York timezone to 11-04-2018 01:00 and 02:00 EDT which are actually 01:00 EDT and 01:00 EST.
I understand why those values are different, but they should be equal after converting them to the TIMESTAMP without time zone data type (the my_date_ny_ts column), since this type doesn't contain any information about timezone and daylight saving status (see the tdz_ny_ts values). Only after I convert the values back to the TIMESTAMP WITH TIMEZONE type (the my_date_ny_ts_tz) they become equal.
I don't need a workaround (already have it), just wondering if this behavior is an Oracle bug or by misunderstanding:
select count(*), my_date_ny_ts_tz from (
SELECT
mydate, -- timestamp with timezone
to_char( mydate, 'TZD') as tdz, -- daylight savings flag - VALUES are NULL because timezone is an offset
mydate AT TIME ZONE 'America/New_York' AS mydate_ny, -- timestamp with timezone in EST timezone
to_char( mydate AT TIME ZONE 'America/New_York', 'TZD') as tdz_ny, --timestamp with timezone in EST timezone - daylight savings flag - RETURNS EDT FOR ONE EST FOR SECOND - RIGHT
cast(mydate AT TIME ZONE 'America/New_York' as timestamp) as my_date_ny_ts,--cast to timestamp without timezone - GROUP BY RETURNS TWO ROWS - BUG?
to_char( cast(mydate AT TIME ZONE 'America/New_York' as timestamp) , 'TZD') as tdz_ny_ts,--cast to timestamp without timezone - daylight savings flag - both values are null so why the group by on the prev field doesn't work?
cast(mydate AT TIME ZONE 'America/New_York' as timestamp) AT TIME ZONE 'America/New_York' as my_date_ny_ts_tz,--cast back to timestamp with timezone in EST timezone - NOW GROUP BY RETURNS ONE ROW
to_char( cast(mydate AT TIME ZONE 'America/New_York' as timestamp) AT TIME ZONE 'America/New_York', 'TZD') as tdz_ny_ts_tz--daylight savings flag of the prev field - both are EST - RIGHT
FROM
(
SELECT
to_timestamp_tz('11/04/2018 00:00:00 -05:00','mm/dd/yyyy hh24:mi:ss TZH:TZM') AS mydate
FROM
dual
UNION
SELECT
to_timestamp_tz('11/04/2018 00:00:00 -06:00','mm/dd/yyyy hh24:mi:ss TZH:TZM') AS mydate
FROM
dual
)
) group by my_date_ny_ts_tz
My version is the following, but it happens in 12c as well:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
"CORE 11.2.0.4.0 Production"
TNS for 64-bit Windows: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
Thanks
oracle timezone timestamp dst timestamp-with-timezone
I have a strange behavior of Oracle DB with TIMESTAMP and daylight saving.
The following query produces different results when grouping by different columns and it is not clear why.
When grouping by my_date_ny_ts it returns two different rows and when by my_date_ny_ts_tz - the result is only one row (the right one for me).
Please note the values are for the 11/04/2018 00:00:00 -05:00 and 11/04/2018 00:00:00 -06:00 that are converted to the New_York timezone to 11-04-2018 01:00 and 02:00 EDT which are actually 01:00 EDT and 01:00 EST.
I understand why those values are different, but they should be equal after converting them to the TIMESTAMP without time zone data type (the my_date_ny_ts column), since this type doesn't contain any information about timezone and daylight saving status (see the tdz_ny_ts values). Only after I convert the values back to the TIMESTAMP WITH TIMEZONE type (the my_date_ny_ts_tz) they become equal.
I don't need a workaround (already have it), just wondering if this behavior is an Oracle bug or by misunderstanding:
select count(*), my_date_ny_ts_tz from (
SELECT
mydate, -- timestamp with timezone
to_char( mydate, 'TZD') as tdz, -- daylight savings flag - VALUES are NULL because timezone is an offset
mydate AT TIME ZONE 'America/New_York' AS mydate_ny, -- timestamp with timezone in EST timezone
to_char( mydate AT TIME ZONE 'America/New_York', 'TZD') as tdz_ny, --timestamp with timezone in EST timezone - daylight savings flag - RETURNS EDT FOR ONE EST FOR SECOND - RIGHT
cast(mydate AT TIME ZONE 'America/New_York' as timestamp) as my_date_ny_ts,--cast to timestamp without timezone - GROUP BY RETURNS TWO ROWS - BUG?
to_char( cast(mydate AT TIME ZONE 'America/New_York' as timestamp) , 'TZD') as tdz_ny_ts,--cast to timestamp without timezone - daylight savings flag - both values are null so why the group by on the prev field doesn't work?
cast(mydate AT TIME ZONE 'America/New_York' as timestamp) AT TIME ZONE 'America/New_York' as my_date_ny_ts_tz,--cast back to timestamp with timezone in EST timezone - NOW GROUP BY RETURNS ONE ROW
to_char( cast(mydate AT TIME ZONE 'America/New_York' as timestamp) AT TIME ZONE 'America/New_York', 'TZD') as tdz_ny_ts_tz--daylight savings flag of the prev field - both are EST - RIGHT
FROM
(
SELECT
to_timestamp_tz('11/04/2018 00:00:00 -05:00','mm/dd/yyyy hh24:mi:ss TZH:TZM') AS mydate
FROM
dual
UNION
SELECT
to_timestamp_tz('11/04/2018 00:00:00 -06:00','mm/dd/yyyy hh24:mi:ss TZH:TZM') AS mydate
FROM
dual
)
) group by my_date_ny_ts_tz
My version is the following, but it happens in 12c as well:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
"CORE 11.2.0.4.0 Production"
TNS for 64-bit Windows: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
Thanks
oracle timezone timestamp dst timestamp-with-timezone
oracle timezone timestamp dst timestamp-with-timezone
asked Nov 21 '18 at 11:52
D.SmelianskyD.Smeliansky
31
31
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Could be a bug in Oracle. You can shorten the query to this:
SELECT
TO_CHAR(CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP), 'yyyy-mm-dd hh24:mi:ss') AS my_date_ny_ts,
DUMP(CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP)) AS my_date_ny_ts_dump
FROM DUAL
UNION ALL
SELECT
TO_CHAR(CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP), 'yyyy-mm-dd hh24:mi:ss'),
DUMP(CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP))
FROM DUAL;
+--------------------------------------------------------------------------------------+
|MY_DATE_NY_TS |MY_DATE_NY_TS_DUMP |
+--------------------------------------------------------------------------------------+
|2018-11-04 01:00:00|Typ=187 Len=20: 226,7,11,4,1,0,0,0,0,0,0,0,252,0,3,0,100,0,11,3 |
|2018-11-04 01:00:00|Typ=187 Len=20: 226,7,11,4,1,0,0,48,0,0,0,0,251,0,3,44,100,0,48,44|
+--------------------------------------------------------------------------------------+
As you see the timestamp values are the same, however the DUMP()
values are different, i.e. you get two rows if you make GROUP BY
.
You can run it slightly different. Actually I would expect the same result as above (no matter wether you consider that as correct or not) but it is different:
WITH t AS
(SELECT
CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP) AS my_date_ny_ts
FROM DUAL
UNION ALL
SELECT
CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP)
FROM DUAL)
SELECT TO_CHAR(my_date_ny_ts, 'yyyy-mm-dd hh24:mi:ss') AS my_date_ny_ts,
DUMP(my_date_ny_ts) AS my_date_ny_ts_dump
FROM t;
+--------------------------------------------------------------------------------------+
|MY_DATE_NY_TS |MY_DATE_NY_TS_DUMP |
+--------------------------------------------------------------------------------------+
|2018-11-04 01:00:00|Typ=180 Len=7: 120,118,11,4,2,1,1 |
|2018-11-04 01:00:00|Typ=180 Len=7: 120,118,11,4,2,1,1 |
+--------------------------------------------------------------------------------------+
This looks strange to me. Although I made CAST(... AS TIMESTAMP)
for both, once I get Typ=187
and once I get Typ=180
in DUMP.
Looks like the SQL type TIMESTAMP
180 (see Oracle Built-In Data Types) behaves different than the PL/SQL type TIMESTAMP
187 (see PACKAGE SYS.dbms_types
) - but I don't know why.
For the workaround I would suggest to use function SYS_EXTRACT_UTC(...)
rather than CAST(... AS TIMESTAMP)
.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53411470%2foracle-strange-behavior-when-grouping-by-a-timestamp-field-when-the-values-are-o%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Could be a bug in Oracle. You can shorten the query to this:
SELECT
TO_CHAR(CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP), 'yyyy-mm-dd hh24:mi:ss') AS my_date_ny_ts,
DUMP(CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP)) AS my_date_ny_ts_dump
FROM DUAL
UNION ALL
SELECT
TO_CHAR(CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP), 'yyyy-mm-dd hh24:mi:ss'),
DUMP(CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP))
FROM DUAL;
+--------------------------------------------------------------------------------------+
|MY_DATE_NY_TS |MY_DATE_NY_TS_DUMP |
+--------------------------------------------------------------------------------------+
|2018-11-04 01:00:00|Typ=187 Len=20: 226,7,11,4,1,0,0,0,0,0,0,0,252,0,3,0,100,0,11,3 |
|2018-11-04 01:00:00|Typ=187 Len=20: 226,7,11,4,1,0,0,48,0,0,0,0,251,0,3,44,100,0,48,44|
+--------------------------------------------------------------------------------------+
As you see the timestamp values are the same, however the DUMP()
values are different, i.e. you get two rows if you make GROUP BY
.
You can run it slightly different. Actually I would expect the same result as above (no matter wether you consider that as correct or not) but it is different:
WITH t AS
(SELECT
CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP) AS my_date_ny_ts
FROM DUAL
UNION ALL
SELECT
CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP)
FROM DUAL)
SELECT TO_CHAR(my_date_ny_ts, 'yyyy-mm-dd hh24:mi:ss') AS my_date_ny_ts,
DUMP(my_date_ny_ts) AS my_date_ny_ts_dump
FROM t;
+--------------------------------------------------------------------------------------+
|MY_DATE_NY_TS |MY_DATE_NY_TS_DUMP |
+--------------------------------------------------------------------------------------+
|2018-11-04 01:00:00|Typ=180 Len=7: 120,118,11,4,2,1,1 |
|2018-11-04 01:00:00|Typ=180 Len=7: 120,118,11,4,2,1,1 |
+--------------------------------------------------------------------------------------+
This looks strange to me. Although I made CAST(... AS TIMESTAMP)
for both, once I get Typ=187
and once I get Typ=180
in DUMP.
Looks like the SQL type TIMESTAMP
180 (see Oracle Built-In Data Types) behaves different than the PL/SQL type TIMESTAMP
187 (see PACKAGE SYS.dbms_types
) - but I don't know why.
For the workaround I would suggest to use function SYS_EXTRACT_UTC(...)
rather than CAST(... AS TIMESTAMP)
.
add a comment |
Could be a bug in Oracle. You can shorten the query to this:
SELECT
TO_CHAR(CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP), 'yyyy-mm-dd hh24:mi:ss') AS my_date_ny_ts,
DUMP(CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP)) AS my_date_ny_ts_dump
FROM DUAL
UNION ALL
SELECT
TO_CHAR(CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP), 'yyyy-mm-dd hh24:mi:ss'),
DUMP(CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP))
FROM DUAL;
+--------------------------------------------------------------------------------------+
|MY_DATE_NY_TS |MY_DATE_NY_TS_DUMP |
+--------------------------------------------------------------------------------------+
|2018-11-04 01:00:00|Typ=187 Len=20: 226,7,11,4,1,0,0,0,0,0,0,0,252,0,3,0,100,0,11,3 |
|2018-11-04 01:00:00|Typ=187 Len=20: 226,7,11,4,1,0,0,48,0,0,0,0,251,0,3,44,100,0,48,44|
+--------------------------------------------------------------------------------------+
As you see the timestamp values are the same, however the DUMP()
values are different, i.e. you get two rows if you make GROUP BY
.
You can run it slightly different. Actually I would expect the same result as above (no matter wether you consider that as correct or not) but it is different:
WITH t AS
(SELECT
CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP) AS my_date_ny_ts
FROM DUAL
UNION ALL
SELECT
CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP)
FROM DUAL)
SELECT TO_CHAR(my_date_ny_ts, 'yyyy-mm-dd hh24:mi:ss') AS my_date_ny_ts,
DUMP(my_date_ny_ts) AS my_date_ny_ts_dump
FROM t;
+--------------------------------------------------------------------------------------+
|MY_DATE_NY_TS |MY_DATE_NY_TS_DUMP |
+--------------------------------------------------------------------------------------+
|2018-11-04 01:00:00|Typ=180 Len=7: 120,118,11,4,2,1,1 |
|2018-11-04 01:00:00|Typ=180 Len=7: 120,118,11,4,2,1,1 |
+--------------------------------------------------------------------------------------+
This looks strange to me. Although I made CAST(... AS TIMESTAMP)
for both, once I get Typ=187
and once I get Typ=180
in DUMP.
Looks like the SQL type TIMESTAMP
180 (see Oracle Built-In Data Types) behaves different than the PL/SQL type TIMESTAMP
187 (see PACKAGE SYS.dbms_types
) - but I don't know why.
For the workaround I would suggest to use function SYS_EXTRACT_UTC(...)
rather than CAST(... AS TIMESTAMP)
.
add a comment |
Could be a bug in Oracle. You can shorten the query to this:
SELECT
TO_CHAR(CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP), 'yyyy-mm-dd hh24:mi:ss') AS my_date_ny_ts,
DUMP(CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP)) AS my_date_ny_ts_dump
FROM DUAL
UNION ALL
SELECT
TO_CHAR(CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP), 'yyyy-mm-dd hh24:mi:ss'),
DUMP(CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP))
FROM DUAL;
+--------------------------------------------------------------------------------------+
|MY_DATE_NY_TS |MY_DATE_NY_TS_DUMP |
+--------------------------------------------------------------------------------------+
|2018-11-04 01:00:00|Typ=187 Len=20: 226,7,11,4,1,0,0,0,0,0,0,0,252,0,3,0,100,0,11,3 |
|2018-11-04 01:00:00|Typ=187 Len=20: 226,7,11,4,1,0,0,48,0,0,0,0,251,0,3,44,100,0,48,44|
+--------------------------------------------------------------------------------------+
As you see the timestamp values are the same, however the DUMP()
values are different, i.e. you get two rows if you make GROUP BY
.
You can run it slightly different. Actually I would expect the same result as above (no matter wether you consider that as correct or not) but it is different:
WITH t AS
(SELECT
CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP) AS my_date_ny_ts
FROM DUAL
UNION ALL
SELECT
CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP)
FROM DUAL)
SELECT TO_CHAR(my_date_ny_ts, 'yyyy-mm-dd hh24:mi:ss') AS my_date_ny_ts,
DUMP(my_date_ny_ts) AS my_date_ny_ts_dump
FROM t;
+--------------------------------------------------------------------------------------+
|MY_DATE_NY_TS |MY_DATE_NY_TS_DUMP |
+--------------------------------------------------------------------------------------+
|2018-11-04 01:00:00|Typ=180 Len=7: 120,118,11,4,2,1,1 |
|2018-11-04 01:00:00|Typ=180 Len=7: 120,118,11,4,2,1,1 |
+--------------------------------------------------------------------------------------+
This looks strange to me. Although I made CAST(... AS TIMESTAMP)
for both, once I get Typ=187
and once I get Typ=180
in DUMP.
Looks like the SQL type TIMESTAMP
180 (see Oracle Built-In Data Types) behaves different than the PL/SQL type TIMESTAMP
187 (see PACKAGE SYS.dbms_types
) - but I don't know why.
For the workaround I would suggest to use function SYS_EXTRACT_UTC(...)
rather than CAST(... AS TIMESTAMP)
.
Could be a bug in Oracle. You can shorten the query to this:
SELECT
TO_CHAR(CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP), 'yyyy-mm-dd hh24:mi:ss') AS my_date_ny_ts,
DUMP(CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP)) AS my_date_ny_ts_dump
FROM DUAL
UNION ALL
SELECT
TO_CHAR(CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP), 'yyyy-mm-dd hh24:mi:ss'),
DUMP(CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP))
FROM DUAL;
+--------------------------------------------------------------------------------------+
|MY_DATE_NY_TS |MY_DATE_NY_TS_DUMP |
+--------------------------------------------------------------------------------------+
|2018-11-04 01:00:00|Typ=187 Len=20: 226,7,11,4,1,0,0,0,0,0,0,0,252,0,3,0,100,0,11,3 |
|2018-11-04 01:00:00|Typ=187 Len=20: 226,7,11,4,1,0,0,48,0,0,0,0,251,0,3,44,100,0,48,44|
+--------------------------------------------------------------------------------------+
As you see the timestamp values are the same, however the DUMP()
values are different, i.e. you get two rows if you make GROUP BY
.
You can run it slightly different. Actually I would expect the same result as above (no matter wether you consider that as correct or not) but it is different:
WITH t AS
(SELECT
CAST(TIMESTAMP '2018-11-04 00:00:00 -05:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP) AS my_date_ny_ts
FROM DUAL
UNION ALL
SELECT
CAST(TIMESTAMP '2018-11-04 00:00:00 -06:00' AT TIME ZONE 'America/New_York' AS TIMESTAMP)
FROM DUAL)
SELECT TO_CHAR(my_date_ny_ts, 'yyyy-mm-dd hh24:mi:ss') AS my_date_ny_ts,
DUMP(my_date_ny_ts) AS my_date_ny_ts_dump
FROM t;
+--------------------------------------------------------------------------------------+
|MY_DATE_NY_TS |MY_DATE_NY_TS_DUMP |
+--------------------------------------------------------------------------------------+
|2018-11-04 01:00:00|Typ=180 Len=7: 120,118,11,4,2,1,1 |
|2018-11-04 01:00:00|Typ=180 Len=7: 120,118,11,4,2,1,1 |
+--------------------------------------------------------------------------------------+
This looks strange to me. Although I made CAST(... AS TIMESTAMP)
for both, once I get Typ=187
and once I get Typ=180
in DUMP.
Looks like the SQL type TIMESTAMP
180 (see Oracle Built-In Data Types) behaves different than the PL/SQL type TIMESTAMP
187 (see PACKAGE SYS.dbms_types
) - but I don't know why.
For the workaround I would suggest to use function SYS_EXTRACT_UTC(...)
rather than CAST(... AS TIMESTAMP)
.
edited Nov 22 '18 at 6:48
answered Nov 21 '18 at 13:10
Wernfried DomscheitWernfried Domscheit
24.8k43261
24.8k43261
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53411470%2foracle-strange-behavior-when-grouping-by-a-timestamp-field-when-the-values-are-o%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown