Oracle date comparison as string and as date - oracle

1) Why is that this doesn't works
select * from table where trunc(field1)=to_date('25-AUG-15','DD-MON-YY');
select * from table where trunc(field1)=to_date('25/Aug/15','DD/MON/YY');
row is returned in above cases.
So, does this mean that no matter what format the date is there in field1, if it is the valid date and matches with 25th August, it will be returned ( it won't care what format specifier we specify at the right side of the query i.e. DD-MON-YY or DD/MON/YY or anything else) ?
2) but comparsion as string exactly works:
select * from table where to_char(field1)=to_char(to_date
('25/AUG/15','DD/MON/YY'), 'DD/MON/YY');
no row is returned as the comparison is performed exactly.
I have field1 as '25-AUG-15' ( although it can be viewed differently doing alter session NLS_DATE_FORMAT...)
field1 is of DATE type
Any help in understanding this is appreciated specifically with respect to point 1

The DATE data type does not have format -- it's simply a number. So, a DATE 25-Aug-2015 is the same as DATE 25/AUG/15, as well as DATE 2015-08-15, because it's the same DATE.
Strings, on the other hand, are collections of characters, so '25-Aug-2015' is obviously different from '25/AUG/15'.
In the first example you are comparing DATE values. In the second example you are comparing strings.

So you have a field of type DATE with value of The 25th of August 2015,
but it could be visualized in different ways, what in fact is named format.
The DATE has format!
The DATE has implicit format defined by Oracle, in your case it is DD-MON-YY, because you see your field as 25-AUG-15.
You can select your data without TO_DATE conversion, just matching this default format like this:
select * from table where trunc(field1)='25-AUG-15';
In fact, it's not recommended, because if someone will change the default format, Oracle will not be able to understand that you are going to tell him a DATE.
So the to_date conversion in this case:
select * from table where
trunc(field1)=to_date('25/AUG/15','DD/MON/YY');
is used to specify that you wanna tell to Oracle a DATE type with value of 25th of August 2015, using a diffrent format, specified as second parameter. (DD/MM/YY in this case).

Related

Converting date from DD-MON-YY to DD-MM-YYYY with NLS_DATE_FORMAT

I'm trying to store date type data from Oracle FORMS with format mask as like DD-MM-YYYY but every time it store as like DD/MON/YY.
I already alter session with NLS_DATE_FORMAT, but result is as same as before.
Oracle internal date format that is written in the table is something you can't change in any way, but, in the same time, it is irrelevant. If you are dealing with DATE type column then you should know that it containes both the date and the time. How, where and when you will show it or use it is on you. Here is a sample of a few formats derived from that original Oracle DATE format...
WITH
t AS
(
Select SYSDATE "MY_DATE_COLUMN" From Dual
)
Select
MY_DATE_COLUMN "DATE_DEFAULT_FORMAT",
To_Char(MY_DATE_COLUMN, 'mm-dd-yyyy') "DATE_1",
To_Char(MY_DATE_COLUMN, 'yyyy/mm/dd') "DATE_2",
To_Char(MY_DATE_COLUMN, 'dd.mm.yyyy') "DATE_3",
To_Char(MY_DATE_COLUMN, 'dd.mm.yyyy hh24:mi:ss') "DATE_4"
From t
DATE_DEFAULT_FORMAT
DATE_1
DATE_2
DATE_3
DATE_4
22-OCT-22
10-22-2022
2022/10/22
22.10.2022
22.10.2022 10:59:44
You can find a lot more about the theme at https://www.oracletutorial.com/oracle-basics/oracle-date/
Regards...
In Oracle, 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 those 7 components and it is NEVER stored in any particular human-readable format.
every time it store as like DD/MON/YY.
As already mentioned, no, it does not store a date like that; the database stores dates as 7 bytes.
What you are seeing is that the client application, that you are using to connect to the database, is receiving the 7-byte binary date value and is choosing to convert it to something that is more easily comprehensible to you, the user, and is defaulting to converting the date to a string with the format DD/MON/RR.
What you should be doing is changing how the dates are displayed by the client application by either:
Change the settings in the Toad (View > Toad Options > Data Grids > Data and set the Date Format option) and allow Toad to implicitly format the string; or
Use TO_CHAR to explicitly format the date (TO_CHAR(column_name, 'DD-MM-YYYY')).
I'm trying to store data as like DD-MM-YYYY.
If you want to store a date then STORE it as a date (which has no format) and format it when you DISPLAY it.
If you have a valid business case to store it with a format then you will need to store it as a string, rather than as a date, because you can format strings; however, this is generally considered bad practice and should be avoided.
Sadman, to add to what others have posted I suggest you do not write your applications with reliance on the NLS_DATE_FORMAT parameter but rather you screens and application should specify the expected DATE entry format and the code should use the TO_DATE function to store the data into the database. All application SQL should use the TO_CHAR function to format date output for display.

How to make a constraint on DATE FORMAT in ORACLE

say my usual Date format is '14-jan-2019' and i want my date to only be accepted as 'YYYY-MM-DD' how do i do that? and can i change jan to an actual number?
In my opinion, the right / correct way to do that is to declare your date column (or variable or whatever it is) as DATE, e.g.
create table test (date_column date);
or
declare
l_date_variable date;
begin
...
Doing so, you'd let the database take care about valid values.
You'd then be able to enter data any way you want, using any valid date format mask, e.g.
to_date('06.01.2020', 'dd.mm.yyyy')
date '2020-01-06'
to_date('2020-06-01', 'yyyy-dd-mm')
etc. - all those values would be valid.
A DATE data type has no format - it is stored internally as 7-bytes representing year (2 bytes) and month, day, hour, minute and second (1 byte each).
'14-JAN-2019' is not a date - it is a text literal.
If you want to store date values then use a DATE data type.
If you want to only accept strings of a specific format as input then in whatever user interface you use to talk to the database then accept only that format. If you are converting strings to DATEs and wanting an exact format then you can use:
TO_DATE( '2019-01-14', 'fxYYYY-MM-DD' )
Note: the fx format model will mean that the exact format is expected and the typical string-to-date conversion rules will not be applied.

How to Insert a Timestamp in Oracle in a Specific Format

I am at a loss as how to insert the current time in a different format than the default. Can somebody help explain?
Here is how my table was created:
CREATE TABLE ACTIVITY_LOG
(
TIME TIMESTAMP NOT NULL
, ACTIVITY VARCHAR2(200) NOT NULL
);
My insert command works:
insert into activity_log
values (localtimestamp,'blah');
But how do i insert the localtimestamp value into my table in a different format using the various MM DD YY HH MM SS tags? I've tried the following, but it gives me the ORA-1830: date format picture ends before converting entire input string error.
insert into activity_log
values (to_timestamp(localtimestamp,'YYYY/MM/DD'),'blah');
You don't insert a timestamp in a particular format. Timestamps (and dates) are stored in the database using an internal representation, which is betwen 7 and 11 bytes depending on the type and precision. There is more about that in this question, among others.
Your client or application decides how to display the value in a human-readable string form.
When you do:
to_timestamp(localtimestamp,'YYYY/MM/DD')
you are implicitly converting the localtimestamp to a string, using your session's NLS settings, and then converting it back to a timestamp. That may incidentally change the value - losing precision - but won't change how the value is stored internally. In your case the mismatch between the NLS setting and the format you are supplying is leading to an ORA-01830 error.
So your first insert is correct (assuming you really want the session time, not the server time). If you want to see the stored values in a particular format then either change your client session's NLS settings, or preferably format it explicitly when you query it, e.g.:
select to_char(time, 'YYYY-MM-DD HH24:MI:SS.FF3') from activity_log
You don't seem to provide any indication of what your 'localtimestamp' is - is that pseudocode? A variable name? A column you haven't shown the definition for?
What data type is 'localtimestamp'? What data does it contain? Pertinent questions as other answers point out, because if it truly is a time stamp then oracle will be converting it to a string for you, before passing that string to to_timestamp() in your final query. Your initial stab at it should just work if the variable is a timestamp, containing a timestamp
Ultimately "date format picture ends" means "you passed me a string looking like '2017-05-17 12:45:59', but claimed it was only 'yyyy-mm-dd'. What was I expected to do with the rest of it?"
Your current final comment on your question "I was hoping to look in the table and see a useful looking time" - that's your query tool's problem. Have a look in the setting of your query tool and change the date format it displays. As has been noted, dates in oracle are stored as a decimal number days since a certain moment in time. If 0 represents 01 Jan 1970, then 1.75 represents 6pm on the 2 Jan 1970. It is up to the end program the user is using, to format the date into something you like.. you cannot "insert a timestamp with a different format" because time stamps don't have a format any more than a number like 1.75 has a format. It is what your query does with it when it gets it out, that gives it the format:
To_char(timestampcol, 'yyyy mm did')
To-char(tomestampcol, 'mon dd yyyy')
These use oracles built in date formatter, that turns that decimal number of the date into a string in the given format; you will see a string.. or you can just write "select * from table" and run it in TOAD and toad will show you the dates according to the format in settings, or you can write a c# program and get a load of date objects out and call my date.ToString("yyyy-MM-dd") on them to format them. The idea I'm trying to get across is that you don't pick the date format on the way in, you pick it on the way out, if you don't like what you're looking at, you have to change it on the way out, not the way in

Oracle - Date Format

I need your assistance with converting Oracle dates.
I have a column that stores dates like this 20150731 00:00:34.220. However, I would like to show the column like this 20150731 but when I run a simple select statement to test output I get the following error.
select TO_DATE('20150731 00:00:34.550','YYYYMMDD')
from dual
Error
ORA-01830: date format picture ends before converting entire input string
This query
select TO_DATE('20150731 00:00:34.550','YYYYMMDD')
from dual
leads to error
ORA-01830: date format picture ends before converting entire input string
because you pass string with length 22 characters, but at the same time you pass date format with 8 characters, which obviously doesn't correspond to string. You should write the query as
select to_timestamp('20150731 00:00:34.550','yyyymmdd hh24:mi:ss.ff3')
from dual
As for your table, since you have varchar2 column with dates, you have to take care about table content. Query requires exect matching of the source string and date format.
If you want to show only date without time and you don't need to process this string as date, you can make just
select substr('20150731 00:00:34.550', 1, 8)
from dual
What is the data type of the column? If it is DATE (as it should be) then not it is not stored in the format you say. It is stored in an internal binary format. You would/should use the to_char function to DISPLAY it in whatever format you choose. If you do not use the to_char function, it will be displayed in the format specified by NLS_DATE_FORMAT, which can be specified at several locations.
As for your example, you passed a string format of yyyymmd hh:mi:ss.fff', but you provided a description mask of only YYYYMMDD. It doesn't know what to do with time component. In addition to that when you SELECT TO_DATE, oracle also has to do an implied TO_CHAR to convert it back to a string for display purposes.
In addition, you provided your to_date with a character string that included fractions of seconds. A DATE data type only resolves to seconds. If you need fractional seconds, you need to use TIMESTAMP, not DATE.
If your column is a varchar and you need a date output:
select TO_DATE(substr('20150731 00:00:34.550', 1, 8),'YYYYMMDD') from dual
If it's in a date format and you need a string output:
select to_char(your_column, 'YYYYMMDD') from your_table
Is that being stored in an Oracle datetime column? If not, you may have to do some manipulation to get it into a DD-MON-YYYY format. If it is being stored as a text string you could use SUBSTR( Date_field, Start_Position, Length) to get the first 8 characters. check out this link SUBSTR
Working on the assumption that you're not trying to change the value in the column, and are just trying to show it in the YYYYMMDD format -
As mentioned by a_horse_with_no_name, you'll just need to convert it to a character string. In this example I used systimestamp as my date:
SELECT TO_CHAR(systimestamp,'YYYYMMDD') FROM DUAL
Result:
20160121
That should give you the YYYYMMDD format you want to display.

Compare two times in oracle

In Oracle :
My table has a timestamp column with time value of '02-NOV-11 12.00.00.000000000 AM' .
I tried to compare two dates:
select id from table1 where mytime = '02-NOV-11'
But it returns no records. Why?
Thanks!!!
I suspect it may be the default date format that is causing the problem, since the query works fine for me. It is not good practice to write queries that compare dates with strings, since this requires Oracle to format the string into a date using the default format, which may not be as you expect. It is better to use ANSI date literals like this:
select id from table1 where mytime = date '2011-11-02';
ANSI date literals must be in the format date 'yyyy-mm-dd', so there is no ambiguity about format.
A reference for datetime literals

Resources