Oracle default Timestamp format - sql

I just set default timestamp format as
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH:MI:SS.FF'
When I insert the data into the table the timestamp inserted as,
0014-08-11 04:45:24.000000000
When I query
SELECT SYSTIMESTAMP FROM DUAL
I get:
11-AUG-14 06.14.58.400000000 PM +04:00
But I want the default timestamp as 2014-07-22 05:54:18.000000000.
It would be appreciated if some one could help me on this.

SYSTIMESTAMP returns data type TIMESTAMP WITH TIMEZONE. So you either need to cast it to a plain TIMESTAMP:
SELECT CAST(SYSTIMESTAMP AS TIMESTAMP) FROM DUAL;
CAST(SYSTIMESTAMPASTIMESTAMP)
-----------------------------
2014-08-11 15:27:11.091862000
Or set the separate NLS_TIMESTAMP_TZ_FORMAT parameter:
ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
SELECT SYSTIMESTAMP FROM DUAL;
SYSTIMESTAMP
----------------------
2014-08-11 15:27:11.35
1526000
Either way you're losing the time zone information, which may or may not matter to you.
But this doesn't have anything to do with querying values from a TIMESTAMP (without time zone) column in your table. The value in the table has no format incidentally; the NLS settings when you insert will not affect how it is stored or how it is displayed when queried. You need to specify the format at query time as well as at insert time - and preferably using explicit format models with TO_TIMESTAMP() and TO_CHAR() rather than replying on NLS settings, which you might not be able to control.
You should also be using HH24 since you no longer have the AM/PM marker.

There are two solutions to this :
1. Convert TIMESTAMP/DATE format in Oracle client (Applicable only for that session)
alter session set nls_timestamp_format='YYYY-MM-DD HH24:MI:SS.FF6';
2. Define nls_timestamp_format in init.ora
nls_timestamp_format='YYYY-MM-DD HH24:MI:SS.FF6';

Related

TO_UTC_TIMESTAMP_TZ not returning Month name [duplicate]

I firstly run the following command, and get the following result:
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 10:21:40
This is the format I want to have a TIMESTAMP object stored in.
When I convert it back though, it does not come in the format I want:
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 10.21.40.000000000 AM
In fact, it changes 2018 to be at the end, sets 07 to be "JUL" and the 10 is now at the front. Also the time is separated by dots, has many 0's and an AM.
How can I fix this? I am new to SQL development so I am not sure about the formatting.
Thank you so much
As #Gordon said, timestamps (and dates) are not stored in a format you would recognise Oracle uses an internal representation that you never really need to know about or examine (but it is documented if you're interested in that sort of thing).
When you query a timestamp it is displayed using your client's NLS settings, unless you have a client that overrides those. I can set my session up to match what you are seeing:
alter session set nls_timestamp_format = 'DD-MON-RR HH.MI.SS.FF AM';
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 15:37:31
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 03.37.31.000000000 PM
And I can change it see what you want to see:
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS';
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHA
-------------------
2018-07-10 15:37:32
But all you are doing is converting from a timestamp with time zone (which is what systimestamp is) to a string and then back to a timestamp. You are losing the time zone portion, and any fractional seconds; which you could also do with a cast:
select cast(systimestamp as timestamp(0)) from dual;
CAST(SYSTIMESTAMPAS
-------------------
2018-07-10 15:37:32
You can see the timezone and fraction seconds with your default timestamp_tz format:
select systimestamp from dual;
SYSTIMESTAMP
------------------------------------
2018-07-10 15:37:33.776469000 +01:00
and change it with a different alter:
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS.FF3 TZH:TZM';
select systimestamp from dual;
SYSTIMESTAMP
------------------------------
2018-07-10 15:37:34.070 +01:00
Which isn't entirely relevant if you're really talking about storing timestamps in a table, but shows that there are variations.
In your table make the data type timestamp (or timestamp with time zone or timestamp with local time zone), and only worry about formatting the value as a string for presentation to the end user, at the last possible moment.
When you do need to display it, if the display format is important to you then use to_char() with an explicit format mask - do not assume that anyone else running your queries will have the same NLS settings. As you can see, it's easy to change those to modify the output. (Most clients have a way to let you set the defaults so you don't have to do the same alter commands every time you connect; e.g. in SQL Developer, from Tools->Preferences->Database->NLS). If you want to always show the same format then use something like:
select to_char(your_column, 'YYYY-MM-DD HH24:MI:SS') as column_alias
from your_table
where your_column < timestamp '2018-01-01 00:00:00'
which also shows the column value being filtered (as a timestamp still) using a timestamp literal.
This is the format I want to have a TIMESTAMP object stored in.
This is a common misconception - timestamp (and date) data types do not have a format; they are stored in the database as 20 bytes (or 7 bytes for dates) representing:
year (2 bytes),
month, day, hour, minute, integer seconds (1 bytes each),
fractional seconds (4 bytes),
time zone offset hours (1 byte),
time zone offset minutes (1 byte),
other data (including time zone location) (7 bytes)
You can see the bytes using the DUMP function:
SELECT DUMP( your_timestamp_column ) FROM your_table;
The database will operate on these 20 bytes without any format. But that would not be useful to display to you, the user, so the user interface you use to access the database (SQL/Plus, SQL Developer, Toad, Java, C#, etc) will receive those raw bytes from the database and will silently format them into a more intelligible format for you, the user.
What you are actually asking is:
How can I get the application I am using to access the Oracle database to change the default format it uses to display TIMESTAMP data types?
For SQL/Plus (and SQL Developer) you can use the NLS_TIMESTAMP_FORMAT session parameter:
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
Then:
SELECT SYSTIMESTAMP FROM DUAL;
Will output:
2018-07-10 16:24:53
However, this only sets the default format for your user's current session; other users can set their own parameters and can change the value during their session so you should not rely on this to provide a consistent formatting.
Instead, if you want to have a TIMESTAMP with a particular format then you should convert it to a datatype which can have a format - a string.
SELECT TO_CHAR( SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS' ) FROM DUAL;
Then it does not matter what the user changes their default timestamp format to - your values will always be formatted how you expect.
So based on your replies above it sounds like you may be trying to do something you don't actually need to do.
As Gordon mentioned, timestamps are stored in an internal format so you can do things with the values. If you have the field stored as a timestamp data type you don't need to care how it's formatted in the database, you just need to care about how it looks for your query at the end. You can display a date field using to_char and still use a date range if you have the query built correctly.
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS')
from dual
WHERE systimestamp <= current_timestamp;
I don't think it is possible to to display the timestamp as you've described without using to_char and losing the data type.

remove milliseconds from datetime type

Trying to remove the milliseconds and the pm/am from the datetime field using Oracle SQL.
My query is:
select created_dt from mydatabase
Output is:
09-NOV-21 12.18.40.490000000 PM
I tried using to_char(created_dt, 'dd-mm-yy hh24:mi:ss') then using to_timestamp to convert back to datetime type but the milliseconds showing again.
A TIMESTAMP data type is stored in a table as a binary data-type with 1-byte for each of century, year-of-century, month, day, hour, minute and second and has up to 6 bytes for fractional seconds. It is NEVER stored with any particular format.
If you want to change the number of fractional digits in a timestamp then you need to use CAST:
SELECT CAST(created_dt AS TIMESTAMP(0))
FROM mydatabase
However, you could just convert it to a DATE (which also has year-to-second components but no fractional seconds):
SELECT CAST(created_dt AS DATE)
FROM mydatabase
Once you have done that then whatever client application you are using (SQL/Plus, SQL Developer, Java, C#, PHP, etc.) will still use its default rules for displaying the TIMESTAMP (or DATE) and those rules may display a certain number of fractional seconds.
If you are using SQL/Plus or SQL Developer (but not if you are using Java, C#, PHP, etc.) then the default format is controlled by the NLS_TIMESTAMP_FORMAT session parameter.
You can alter this using:
-- Display with precision of the data type
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
-- Display with 6-digits precision
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF6';
-- Display with no fractional seconds.
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
But, if you want a consistent method of formatting a TIMESTAMP then use TO_CHAR.
How the DATE or TIMESTAMP data types are stored can't be changed.
But you can change how a query outputs a TIMESTAMP by default for the session.
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
Example:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MON-DD HH24:MI:SS';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
select ts
, CAST(ts AS DATE) dt
, CAST(ts AS TIMESTAMP WITH TIME ZONE) AS tstz
from
(
select
to_timestamp('2021-11-30 23:30:45.123456789', 'YYYY-MM-DD HH24:MI:SS.FF') AS ts
from dual
) q
TS | DT | TSTZ
:------------------ | :------------------- | :-------------------------------
2021-11-30 23:30:45 | 2021-NOV-30 23:30:45 | 30-NOV-21 23.30.45.123457 +00:00
db<>fiddle here

Oracle Data type convert

There are two columns that have created which data type is Date, TimeStart and TimeEnd in my table (EventPlanLine). Well, the insert data is below shows:
Insert into EVENTPLANLINE (TIMESTART,TIMEEND)
values (to_date('25-OCT-18 8:00:00','DD-MON-RR HH24:MI:SS'),
to_date('25-OCT-18 17:00:00','DD-MON-RR HH24:MI:SS'));
Result:
25-OCT-18, 25-OCT-18
Forgive me about I only pick up those two columns data insertion to display. The result of the data presentation in the column shows DD-MON-RR format without time. Here is the question, how could the data presents with DD-MON-RR HH24:MI:SS format. I have checked from online resources, I could change NLS_DATE_FORMAT from Oracle, yes, it does and with time as below shows
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-RR HH24:MI:SS'
But the all tables which data type is Date have changed in the database. So is there a solution could change one table date type rather entire database?
A date column does not have a human-readable format; there is an internal representation and the client decides how to display the results (usually based on NOS_DATE_FORMAT), unless you explicitly format a column in your query with to_char().
But the all tables which data type is Date have changed in the database
No, your client is using that setting to display the dates as formatted strings. Notign has changed in the database.
So is there a solution could change one table date type rather entire database?
No, you can't set a format for a column in a table - they are just dates.
All you can do is explicitly format as part of your query; each date can then be formatted differently. Rather contrived but to demonstrate:
alter session set nls_date_format = 'DD-Mon-RR';
select
timestart,
timeend,
to_char(TIMESTART, 'YYYY-MM-DD HH24:MI:SS') as timestart_2,
to_char(TIMEEND, 'FMDay DD/Mon/YYYY HH:MI AM', 'NLS_DATE_LANGUAGE=ENGLISH') as timeend_2
from EVENTPLANLINE;
TIMESTART TIMEEND TIMESTART_2 TIMEEND_2
--------- --------- ------------------- ---------------------------
25-Oct-18 25-Oct-18 2018-10-25 08:00:00 Thursday 25/Oct/2018 5:0 PM
If the result format matters then don't rely on NLS formats as someone else running your code might have different settings in their session. (And as a related note, don't rely on implicit conversions of strings to dates - you aren't here but they often go together...)

How do I get this timestamp in the format I want, Oracle SQL

I firstly run the following command, and get the following result:
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 10:21:40
This is the format I want to have a TIMESTAMP object stored in.
When I convert it back though, it does not come in the format I want:
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 10.21.40.000000000 AM
In fact, it changes 2018 to be at the end, sets 07 to be "JUL" and the 10 is now at the front. Also the time is separated by dots, has many 0's and an AM.
How can I fix this? I am new to SQL development so I am not sure about the formatting.
Thank you so much
As #Gordon said, timestamps (and dates) are not stored in a format you would recognise Oracle uses an internal representation that you never really need to know about or examine (but it is documented if you're interested in that sort of thing).
When you query a timestamp it is displayed using your client's NLS settings, unless you have a client that overrides those. I can set my session up to match what you are seeing:
alter session set nls_timestamp_format = 'DD-MON-RR HH.MI.SS.FF AM';
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 15:37:31
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 03.37.31.000000000 PM
And I can change it see what you want to see:
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS';
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHA
-------------------
2018-07-10 15:37:32
But all you are doing is converting from a timestamp with time zone (which is what systimestamp is) to a string and then back to a timestamp. You are losing the time zone portion, and any fractional seconds; which you could also do with a cast:
select cast(systimestamp as timestamp(0)) from dual;
CAST(SYSTIMESTAMPAS
-------------------
2018-07-10 15:37:32
You can see the timezone and fraction seconds with your default timestamp_tz format:
select systimestamp from dual;
SYSTIMESTAMP
------------------------------------
2018-07-10 15:37:33.776469000 +01:00
and change it with a different alter:
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS.FF3 TZH:TZM';
select systimestamp from dual;
SYSTIMESTAMP
------------------------------
2018-07-10 15:37:34.070 +01:00
Which isn't entirely relevant if you're really talking about storing timestamps in a table, but shows that there are variations.
In your table make the data type timestamp (or timestamp with time zone or timestamp with local time zone), and only worry about formatting the value as a string for presentation to the end user, at the last possible moment.
When you do need to display it, if the display format is important to you then use to_char() with an explicit format mask - do not assume that anyone else running your queries will have the same NLS settings. As you can see, it's easy to change those to modify the output. (Most clients have a way to let you set the defaults so you don't have to do the same alter commands every time you connect; e.g. in SQL Developer, from Tools->Preferences->Database->NLS). If you want to always show the same format then use something like:
select to_char(your_column, 'YYYY-MM-DD HH24:MI:SS') as column_alias
from your_table
where your_column < timestamp '2018-01-01 00:00:00'
which also shows the column value being filtered (as a timestamp still) using a timestamp literal.
This is the format I want to have a TIMESTAMP object stored in.
This is a common misconception - timestamp (and date) data types do not have a format; they are stored in the database as 20 bytes (or 7 bytes for dates) representing:
year (2 bytes),
month, day, hour, minute, integer seconds (1 bytes each),
fractional seconds (4 bytes),
time zone offset hours (1 byte),
time zone offset minutes (1 byte),
other data (including time zone location) (7 bytes)
You can see the bytes using the DUMP function:
SELECT DUMP( your_timestamp_column ) FROM your_table;
The database will operate on these 20 bytes without any format. But that would not be useful to display to you, the user, so the user interface you use to access the database (SQL/Plus, SQL Developer, Toad, Java, C#, etc) will receive those raw bytes from the database and will silently format them into a more intelligible format for you, the user.
What you are actually asking is:
How can I get the application I am using to access the Oracle database to change the default format it uses to display TIMESTAMP data types?
For SQL/Plus (and SQL Developer) you can use the NLS_TIMESTAMP_FORMAT session parameter:
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
Then:
SELECT SYSTIMESTAMP FROM DUAL;
Will output:
2018-07-10 16:24:53
However, this only sets the default format for your user's current session; other users can set their own parameters and can change the value during their session so you should not rely on this to provide a consistent formatting.
Instead, if you want to have a TIMESTAMP with a particular format then you should convert it to a datatype which can have a format - a string.
SELECT TO_CHAR( SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS' ) FROM DUAL;
Then it does not matter what the user changes their default timestamp format to - your values will always be formatted how you expect.
So based on your replies above it sounds like you may be trying to do something you don't actually need to do.
As Gordon mentioned, timestamps are stored in an internal format so you can do things with the values. If you have the field stored as a timestamp data type you don't need to care how it's formatted in the database, you just need to care about how it looks for your query at the end. You can display a date field using to_char and still use a date range if you have the query built correctly.
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS')
from dual
WHERE systimestamp <= current_timestamp;
I don't think it is possible to to display the timestamp as you've described without using to_char and losing the data type.

What is the proper way of formatting date in select query Oracle SQL

For suppose if I want sysdate,
SELECT SYSDATE as system_date FROM DUAL;
should output in the following format
14-Feb-2018 T19:50:02+00:00
i.e.,
DD-MMM-YYYY Thh:mm:ss+HH:MM
Assuming you know the date represents UTC and want the +00:00 part to be fixed:
select to_char(sysdate, 'DD-Mon-YYYY "T"HH24:MI:SS"+00:00"') from dual;
TO_CHAR(SYSDATE,'DD-MON-YYYY"T"HH24:
------------------------------------
14-Feb-2018 T20:13:08+00:00
The format model elements are in the documentation. That includes a section on character literals, which I've used for the fixed T and +00:00 parts.
As #mathguy said, this seems a bit unusual; and you might actually to leave the column as a native date and have your application or reporting tool or whatever format it for you. It depends what exactly you're doing, and whether you actually want a string value directly from the query.
As your updated question now doesn't have that pseudo-timezone, it's now even simpler, but the same idea:
select to_char(sysdate, 'DD-Mon-YYYY "T"HH24:MI:SS') from dual;
TO_CHAR(SYSDATE,'DD-MON-YYYY"T
------------------------------
14-Feb-2018 T20:17:50
If you're working with a data type that knows about time zones - i.e. not a plain DATE or TIMESTAMP - you can include those in the formatting using the appropriate model elements:
select to_char(systimestamp, 'DD-Mon-YYYY "T"HH24:MI:SSTZH:TZM') from dual;
TO_CHAR(SYSTIMESTAMP,'DD-MON-YYYY"T"
------------------------------------
14-Feb-2018 T20:24:58+00:00
which happens to still show +00:00 because my system is in the UK. With a different value it shows something appropriate:
alter session set time_zone = 'AMERICA/NEW_YORK';
select to_char(current_timestamp, 'DD-Mon-YYYY "T"HH24:MI:SSTZH:TZM') from dual;
TO_CHAR(CURRENT_TIMESTAMP,'DD-MON-YY
------------------------------------
14-Feb-2018 T15:28:57-05:00
Notice now I'm using systimestamp and current_timestamp, which are TZ-aware, and not sysdate or current_date which are not - you'l get an error if you try to get the TZH or TZM elements from those.
The format you are requesting doesn't make much sense. +00:00 is the time zone offset (otherwise what is it?) but in Oracle the DATE data type does not know about time zones. Only the Oracle data type TIMESTAMP WITH TIME ZONE should be formatted that way in Oracle.
Here is how this should be done with timestamps WITH TIME ZONE. Note that the standard SYSTIMESTAMP function is a timestamp WITH TIME ZONE. In the query below, you can see how the timestamp is formatted using my session's default, and then using an explicit format model.
SQL> select systimestamp,
2 to_char(systimestamp, 'dd-Mon-yyyy "T"hh24:mi:sstzh:tzm') as ts
3 from dual
4 ;
SYSTIMESTAMP TS
------------------------------------------- ---------------------------
14-FEB-18 12.14.18.537000 PM -08:00 14-Feb-2018 T12:14:18-08:00