Oracle convert Timestamp to Date - sql

I have date like :
2020/05/09T02:40:03
2020/05/16T02:40:03
2020/05/15T02:40:03
I need to convert it into Date format 'dd/mm/yyyy'.
My query
select cast(date_registered as date) as Reg_date from employee
Error:
Literal does not match format string
Note:I have also used TO_Char , TO_Date but not working

First, what you tried to convert to date is not a timestamp, it is a string.
Second, cast(... to date) does not take a format model - it simply relies on your session nls_date_format parameter, which doesn't match the string's date format. (Especially the boilerplate, hard-coded T in the middle, which has no meaning in Oracle.)
You need to_date() with an appropriate format model. Notice the handling of hardcoded string fragments (they appear in double-quotes in the format model).
select to_date(date_registered, 'yyyy/mm/dd"T"hh24:mi:ss') as reg_date
from employee;

In Oracle, a date data type is always stores as 7-bytes consisting of century, year-of-century, month, day, hours, minutes and seconds; so, asking to convert something that has year-to-seconds components to a date does not require you to do anything:
SELECT date_registered AS reg_date FROM employee
Now, if you are storing date_registered as a string data type rather than as a date data type then you need to convert using TO_DATE:
SELECT TO_DATE( date_registered, 'YYYY-MM-DD"T"HH24:MI:SS' ) AS reg_date
FROM employee
However, you should not do this and you should fix the underlying problem that you are storing dates as strings and not dates. You can solve this by converting the data type of the column:
ALTER TABLE employee ADD ( date_registered2 DATE );
UPDATE employee
SET date_registered2 = TO_DATE( date_registered, 'YYYY-MM-DD"T"HH24:MI:SS' );
ALTER TABLE employee DROP COLUMN date_registered;
ALTER TABLE employee RENAME COLUMN date_registered2 TO date_registered;
(Note: The queries below assume that you have "fixed" the table so that the date_registered column has the date data type; if you do not want to do this then you will need to include the TO_DATE conversion as well.)
If you want the output to be a date where the time component is truncated back to midnight then:
SELECT TRUNC( date_registered ) AS reg_date
FROM employee
(Note: The displayed date will still have hours, minutes and seconds components but they will all be zero after being passed through TRUNC.)
If you want it in a specific format, without the time component, then you need to output it as a formatted string (since the date data type does not have an associated format) using TO_CHAR:
SELECT TO_CHAR( date_registered, 'DD/MM/YYYY' ) AS reg_date
FROM employee
db<>fiddle here

Related

My TO_DATE seeming not to function properly

So I am trying to get the section id and the amount of students in that section who enrolled on 02/10/2007. The query returns no results when it should return 6 rows.
The date format its in already is DD-MON-YY.
This is what I have so far:
I took the TO_DATE from another query I did and it worked properly on. The query works without it so im sure its somthing to do with the TO_DATE
SELECT section_id, COUNT(student_id) "ENROLLED"
FROM enrollment
WHERE enroll_date = TO_DATE('2/10/2007', 'MM/DD/YYYY')
GROUP BY section_id
ORDER BY ENROLLED;
Most probably the issue is that there is a fractional date component that you are not taking into account. You can ignore that fractional date component by truncating the column in your query:
SELECT section_id, COUNT(student_id) "ENROLLED"
FROM enrollment
WHERE TRUNC(enroll_date) = TO_DATE('2/10/2007', 'MM/DD/YYYY')
GROUP BY section_id
ORDER BY ENROLLED;
I am assuming that the column enroll_date is of the data type DATE.
Some explanation: Oracle stores dates as described here, it does NOT store a date as you state "The date format its in already is DD-MON-YY.". That is only the format you see the date in, which is determined by the parameter NLS_DATE_FORMAT for your session.
Lets do a quick test with a test table. Create table and check the NLS_DATE_FORMAT form my session.
create table DATE_TST
( id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
test_date DATE
);
INSERT INTO date_tst (test_date) VALUES (SYSDATE);
SELECT value
FROM nls_session_parameters
WHERE parameter = 'NLS_DATE_FORMAT';
DD-MON-YYYY
This is how I will see my dates.
SELECT * FROM date_tst;
04-OCT-2020
So I have todays date. Cool. Now lets see if I can query using that date:
SELECT * FROM date_tst WHERE test_date = TO_DATE('04-OCT-2020','DD-MON-YYYY');
no rows.
No rows are shown because the date format I get my date in does not have a time component. DATE has Year, month, day, hour, minute and seconds. The format only has year, month and day. Lets query the data to check if there is a time component.
SELECT TO_CHAR(test_date,'DD-MON-YYYY HH24:MI:SS') FROM date_tst;
4-OCT-2020 21:12:39
Ah there it is... SYSDATE is the current time up to the second. Now lets try that query again with a more precise date format:
SELECT * FROM date_tst WHERE test_date = TO_DATE('04-OCT-2020 21:12:39','DD-MON-YYYY HH24:MI:SS');
04-OCT-2020
And there is our row. The TRUNC command will cut off the time component:
SELECT TO_CHAR(TRUNC(test_date),'DD-MON-YYYY HH24:MI:SS') FROM date_tst;
04-OCT-2020 00:00:00
So you can simplify your query:
SELECT * FROM date_tst WHERE TRUNC(test_date) = TO_DATE('04-OCT-2020','DD-MON-YYYY');
04-OCT-2020
TO_DATE('2/10/2007', 'MM/DD/YYYY') gives you a date at midnight; however,this will only match values at that instant. What you need to do is either:
TRUNCate the dates in your column back to midnight so that your value matches (however, this will prevent you using an index on the column and you would need to use a function-based index); or
A better solution is to use a date range starting at midnight of the day you want to match and going up-to, but not including, midnight of the next day.
You can do this using TO_DATE or using a date literal:
SELECT section_id,
COUNT(student_id) "ENROLLED"
FROM enrollment
WHERE enroll_date >= DATE '2007-02-10'
AND enroll_date < DATE '2007-02-11'
GROUP BY section_id
ORDER BY ENROLLED;
As an aside:
The date format its in already is DD-MON-YY.
Assuming that the enroll_date column has a DATE data type then this has no format; it is a binary data type consisting of 7 bytes (for century, year-of-century, month, day, hour, minute and second).
What you are seeing is the default date format the user interface applies when it displays the binary date value to the user and you can change it using:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';
(or to whatever format you want.)
This does not change the binary data stored in the column.

Is possible cast as Date with format 'yyyy-MM-dd HH:mm:ss.S'?

I have one table with two columns, id (string) and myTs (bigint).
I want to create a View with this two columns, but myTs must be date type:
CREATE myView AS SELECT id, myToDate(myTs) FROM myTable;
myTs is a timestamp, I want to transform it into a date with timezone Europe/Madrid and format yyyy-MM-dd HH:mm:ss.S.
For example, with myTs = 1167529028000, if I execute:
from_utc_timestamp(myTs, 'Europe/Madrid')
--Result: '2006-12-31 02:37:08.0'
I get the correct result but the type is timestamp, If I try cast it to date I lost the format:
cast(from_utc_timestamp(myTs, 'Europe/Madrid') as date)
--Result: '2006-12-31'
Another option:
date_format(from_utc_timestamp(myTs, 'Europe/Madrid'), 'yyyy-MM-dd HH:mm:ss.S')
--Result: '2006-12-31 02:37:08.0'
The result is String, if I cast as Date, again removes the format:
cast(date_format(from_utc_timestamp(myTs, 'Europe/Madrid'), 'yyyy-MM-dd HH:mm:ss.S') as Date)
--Result: '2006-12-31'
You explained your question pretty well. But unfortunately, it's not possible. If you define any field as date, it is simply a date. The moment you add hours, mins, secs - any of them, you have to define them as a timestamp. Date format will simply have year month and the day.

Oracle to_timestamp

quick question on Oracle To_timestamp.
I have a two fields in a table that are both varchars
1 field contains the YYYYMMDD formatted value
the 2nd field contains the hh24mmss formatted value
Im trying to convert these two fields into a timestamp field,
expected output is DD/MM/YYYY HH24:mm:ss
like '7/23/2015 12:53:04'
however, it gaves me weird result...
like '7/15/0023 12:53:04'
seems year becomes day and day becomes year..
---------- heres my sql ----------------
select
to_date(to_char(to_date('20150723','yyyymmdd'),'yyyymmdd'),'yyyymmdd') dt,
to_char(to_date(SUBSTR('005304000',1,6), 'hh24miss'), 'hh24:mi:ss') tm,
TO_TIMESTAMP(
to_date(to_char(to_date('20150723','yyyymmdd'),'yyyymmdd'),'yyyymmdd') ||
to_char(to_date(SUBSTR('005304000',1,6), 'hh24miss'), 'hh24:mi:ss'), 'yyyy/mm/dd HH24:MI:SS' ) dttm
from dual
You have one layer to much in your conversion chain. And it will be much easier if you concatenate the two columns before converting them:
to_date(date_column||time_column, 'YYYYMMDDHH24MISS')
will return a date and a time (an Oracle DATE includes a time part).
Now that you have a proper date value, you can then format that as you want:
to_char(to_date(date_column||time_column, 'YYYYMMDDHH24MISS'), 'yyyy/mm/dd HH24:MI:SS')
As your "time" column doesn't contain milliseconds there is no real benefit in using to_timestamp.
But you should really fix your table, and store that information in a single DATE (or TIMESTAMP) column. Storing dates in varchar columns is always a very bad choice.

How do I adjust the date time format for an output parameter in Oracle?

I have an output parameter in oracle called outTime of type DATE. The format for this is set as yyyy-mm-dd and I need to be able to include the time from a table when I select into it.
I keep getting an error : date format picture ends before converting entire input string.
here is the insert into statement.
SELECT TO_CHAR(Table_Time, 'YYYY-MM-DD HH24:MI:SS') into outTime
FROM Table_One;
the out parameter is declared as
outTime OUT DATE;
within a stored procedure in a package of other procedures.
I keep finding ways to set the format globally but I only need to set the format for this instance.
Thanks for any insight.
A DATE does not have a format. A string representation of a date has a format but a DATE does not.
If Table_Time is a VARCHAR2 (a string representation of a date) in the format yyyy-mm-dd hh24:mi:ss, then you would want to use TO_DATE to convert the string into a DATE (I assume that there is a single row in table_one in this example, otherwise the SELECT ... INTO will raise a no_data_found or a too_many_rows exception.
SELECT TO_DATE(Table_Time, 'YYYY-MM-DD HH24:MI:SS')
into outTime
FROM Table_One;
If Table_Time is a DATE, you would simply assign it to outTime
SELECT Table_Time
into outTime
FROM Table_One;
When you want to display outTime, you'll need to convert the DATE to a string representation of a date (a VARCHAR2). At that point, you can use the TO_CHAR function.

store dates in oracle

I have a table as
create table Dummy (date_created date)
in oracle.I want to store date in 'dd-mon-yyyy' (12-dec-2010) format.
How should i do this.
Please help.
In Oracle a column created with the DATE datatype just stores the date. It doesn't have a particular format, it just stores the day, month, year, hour, minute, and second. You need to convert from whatever format you have using the TO_DATE function. If you have a text string with the date in 'dd-mon-yyyy' format and you want to put this date into your table you'd use something like
INSERT INTO DUMMY (DATE_CREATED)
VALUES (TO_DATE('01-FEB-2011', 'DD-MON-YYYY');
Going the other way (from DATE column value to character string) you'd use the TO_CHAR function. If you were retrieving a value from your table and wanted to convert it to 'DD-MON-YYYY' format you'd use something like
SELECT TO_CHAR(DATE_CREATED, 'DD-MON-YYYY')
FROM DUMMY;
Share and enjoy.
Use to_date() function. In your case, the syntax would be
insert into Dummy values (to_date('08-09-2010', 'dd-mm-yyyy'));
Here is a link to the detailed help.
The DATE datatype will store date and time information (century, year, month, day, hours, minutes, and seconds) in an internal format in the database. When you get it out of the database, you can choose to display it in whatever format you like.
This information is either created using implicit conversion from a string or explicitly using either the TO_DATE function or the ANSI date literal. If you look in the v$nls_parameters view, this will tell you what the NLS_DATE_FORMAT is which is generally used for the implicit conversion. This may often be defined as DD-MON-RR, which might be why the date will come out as 23-DEC-10 when the query select sysdate from dual is run. (Not entirely sure I'm right about the nls stuff. Correct me if I'm wrong.)
However, all the date information is available if you know how to get it. The query select to_char(sysdate, 'dd-mon-yyyy hh24:mi:ss') from dual will return all the date fields.
Likewise, the insert statement shown below will create a row with a date value in it.
insert into dummy (date_created)
values (to_date('12-dec-2010 12:34:56', 'dd-mon-yyyy hh24:mi:ss'))`
This data can then be retrieved.
select date_created from dummy
This will implicitly convert the date to a character string using the NLS_DATE_FORMAT, providing the output below.
DATE_CREA
---------
23-DEC-10
The full date information is available by explicitly converting the date to a character string.
select to_char(date_created, 'DD-MON-YYYY') as date_created from dummy;
select to_char(date_created, 'DD-MON-YYYY HH24:MI:SS') as date_created
from dummy;
This will provide output in the format you require:
DATE_CREATE
-----------
23-DEC-2010
If you always use the TO_DATE and TO_CHAR functions to convert to/from a date datatype, then you will have fewer problems. Implicit conversion is useful but can cause some confusion or problems.
You can keep and eye here
http://www.techonthenet.com/oracle/functions/to_date.php
use to_date function to save a data with the format you need. I suggest to use SYSDATE updating table and when you need to read data from table use something like that:
dbms_output.put_line(TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS'));
to solve your problem use:
to_date('08/JAN/2010', 'DD/MON/YYYY')
Just use TRUNC(YourDate) if date have time part, it will be truncate time part. Oracle have not just 'DATE' type, 'DATE' always have time part.
However if you do not specify time - it will 00:00:00.
SELECT TRUNC(SYSDATE) from dual
Result:
23-12-2010
Oracle does not support DATE without time part.
You can make it always be an integer date by adding a CHECK constraint:
CREATE TABLE dummy (date_created date CHECK (date_created = TRUNC(date_created)))
, insert it in any format you want:
INSERT
INTO dummy (date_created)
VALUES (TO_DATE('23-DEC-2010', 'dd-mon-yyyy'))
and select it in any format you want:
SELECT TO_CHAR(date_created, 'dd-mon-yyyy')
FROM dummy