date format with inconsistant data Oracle SQL - oracle

I am have a freetext column which a date is input to.
is there a way i can force the output to display the same?
for example some people are entering '2/12/15' others are entering '02/12/2015'
how i can i get the output to pick up the dates and change them to a consistant format?
no idea where to start. I have tried "To_char" but it says 'invalid number'

Actually I believe you want to_date( ):
select to_date('2/12/15', 'mm/dd/rrrr')
from dual;
The 'rrrr' for year will format the year correctly. See date formats here: https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements004.htm

Your best approach here may be to use a PL/SQL function that accepts the string and then attempts a series of date conversions on it with different date format pictures ('DD/MM/YY', 'DD/MM/YYYY' etc) until it finds one that does not raise an exception.
This won't work if some people enter DD/MM/YYYY and others enter MM/DD/YYYY, but will appear to in some cases.

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.

Oracle Varchar2 column with multiple date formats

I have a table (my table ) with a varchar2 column (my_column) , this column inculdes data that may be dates, in almost every known date format. like
dd/mm/yyyy
mm/dd/yyyy
ddMONyyyy
ddmmyyyyy
yymmdd
mm.dd.yy
dd/mm/yyyy hh:24:ss
mm-dd-yyyy
and so many .
Also it could contains a free text data that may be numbers or text.
I need the possible fastest way to retrieve it as a date , and if it's cannot match any date format to retrieve null
Said that this is really a bad and dangerous way to store dates, you could try with something like the following:
select myColumn,
coalesce(
to_date(myColumn default null on conversion error, 'dd/mm/yyyy' ),
to_date(myColumn default null on conversion error, 'yyyy mm dd' ),
... /* all the known formats */
to_date(myColumn default null on conversion error ) /* dangerous */
)
from myTable
Here I would list all the possiblly expected formats, in the right order and trying to avoid the to_date without format mask, which can be really dangerous and give you unexpected results.
The simple answer is: You cannot convert the strings to dates.
You say that possible formats include 'dd/mm/yyyy' and 'mm/dd/yyyy'. So what date would '01/02/2000' be? February 1 or January 2? You cannot know this, so a conversion is impossible.
Having said that, you may want to write a stored procedure where you parse the text yourself and only convert unambiguous strings.
E.g.: Is there a substring containing colons? Then this may be the time part. In the rest of the string: Is there a four-digit number? Then this may be the year. And so on until you are either 100% sure what date/time this is or you cannot unambiguously determine the date (in which case you want to return null).
Example: '13/01/21' looks very much like January 13, 2021. Or do you allow the year 2013 in your table or even 2001 or even 1921 or ...? If you know there can be no year less then, say, 2019 in the table and no year greater than 2021, then the year must be 2021. 13 cannot be the month, so it must be the day, which leaves 01 for the month. If you cannot rule out all other options, then you would have to return null.

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

wrong date format in bi reports oracle

I have the following date which is in varchar2(11) column in database:
select valid_untill from SALES_ORDERS_V where header_id = 7999410;
30-May-2016
Using rtf template and xml source, the report output (PDF) is:
4950-11-19 04:45:49:0
I don't know its equal to "30-May-2016".
Why this is showing this, as I did not do any formating in rtf?
Not familiar with either RTF or XML-Publisher, but whenever you retrieve a date saved in string format, IF you use it as a date in your code and not as a string, you must make sure you retrieve it correctly.
In this case, with your select statement: it shouldn't be select valid-until from... (or is it really misspelled, with two l at the end: valid_until?) If it is meant to be used as a date, it should be
select to_date(valid_until, 'dd-Mon-yyyy') from ...
Really the problem here is that the date is stored as a string and not in the date datatype. Good luck!

Confusion using to_date function to confirm date format

select to_date('07/09/14','yyyy-mm-dd') from dual;
is returning 14-SEP-07
I was expecting it to thrown an exception as the date and the format requested are not the same. Secondly we have slashes in the input date and hypen in the format.
Can someone tell me how to confirm if the input value is of the provided format.
to_date is relatively liberal in attempting to convert the input string using the provided format mask. It generally doesn't concern itself with the specific separator character in the string or in the format mask-- your string could use dashes or slashes or, heck, asterixes if you wanted. Of course, that can mean that you get unexpected results. In this case, for example, the date that is created is in the year 7 (i.e. 2007 years ago). That is a valid date in Oracle but it is highly unlikely to be the date you expect unless you're storing data about ancient Rome.
What, exactly, does it mean to you to "confirm if the input value is of the provided format"? Depending on what you are looking for, you may want to use regular expressions.
REGEXP_LIKE can somewhat do this. Note, this is basic, since it would accept values like 2014-0-32. However, those insane values would fail in whatever you do next in your code, such as to_date().
SELECT 'Yes, valid boss.' is_valid FROM DUAL
WHERE regexp_like('07/09/14','^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$');
no rows selected
.
SELECT 'Yes, valid boss.' is_valid FROM DUAL
WHERE regexp_like('2014-07-09','^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$');
IS_VALID
----------------
Yes, valid boss.
.
SELECT 'Yes, valid boss.' is_valid FROM DUAL
WHERE regexp_like('2014-7-9','^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$');
IS_VALID
----------------
Yes, valid boss.
EDIT: and if you're into PL/SQL, you can do a regex match and throw your own exception ...
DECLARE
v_is_valid INTEGER;
BEGIN
SELECT count(*) INTO v_is_valid FROM DUAL
WHERE regexp_like('07/09/14','^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$');
IF v_is_valid = 0 THEN
raise_application_error (-20400, 'Exception: date was given in the wrong format.');
END IF;
END;
/
*
ORA-20400: Exception: date was given in the wrong format.
TO_DATE() only takes a string and convert it to a date/time in respect to the given format your provided. If it can't find the exact format, it will do its best to determine what could it be. Given your 'yyyy-mm-dd' format, Oracle deduces that the 07 is the year, and the 14 is the day.
You have to write your own function to throw an expected exception or the like to handle the issue, if there is any based on your functional requirements.
So when you select the resulting date, the format that is displayed is actually based on your NLS_DATE_FORMAT system parameter, which gives your resulting date.

Resources