Formatting value of year from SYSDATE - sql

I want to insert the current date into one of the columns of my table. I am using the following:
to_date(SYSDATE, 'yyyy-mm-dd'));
This is working great, but it is displaying the year as '0014'. Is there some way that I can get the year to display as '2014'?

Inserting it as TRUNC(sysdate) would do. Date actually doesn't have a format internally as it is DataType itself. TRUNC() actualy will just trim the time element in the current date time and return today's date with time as 00:00:00
To explain what happened in your case.
say ur NLS_DATE_FORMAT="YY-MM-DD"
The Processing will be like below
select to_date(to_char(sysdate,'YY-MM-DD'),'YYYY-MM-DD') from dual;
Output:
TO_DATE(TO_CHAR(SYSDATE,'YY-MM-DD'),'YYYY-MM-DD')
January, 22 0014 00:00:00+0000
2014 - gets reduced to '14' in first to_char() and later while converted again as YYYY.. it wil be treated as 0014 as the current century detail is last!

to_date is used to convert a string to a date ... try to_char(SYSDATE, 'yyyy-mm-dd') to convert a date to a string.

The to_date function converts a string to a date. SYSDATE is already a date, so what this will do is to first convert SYSDATE to a string, using the session's date format as specified by NLS settings, and then convert that string back to date, using your specified date format (yyyy-mm-dd). That may or may not give correct results, depending on the session's NLS date settings.
The simple and correct solution is to skip the to_date from this and use SYSDATE directly.

Try this to_date(SYSDATE, 'dd-mm-yy')

Related

Adding a day in Oracle but losing hour and minute, and format is also changing

I have a table tab1 in which a column col1 has data type VARCHAR2(50 BYTE) and this column has values like '9/27/21 18:05'
I want to add 1 day to this and I am expecting a result like '9/28/21 18:05'
If I do
TO_TIMESTAMP(col1,'MM/DD/YYYY HH24:MI') + INTERVAL '1' DAY
then I get '28-SEP-21 06.24.00.000000000 PM', and if I do
TO_DATE(col1,'MM/DD/YYYY HH24:MI') + INTERVAL '1' DAY'
then I get '28-SEP-21'.
Please note in both the above cases format is changing.
How can I get the result I want?
DATE and TIMESTAMP values are both binary data types that do NOT have a given format; therefore, when you convert a string to a DATE or a TIMESTAMP then the format you use is NOT stored.
If you want to convert it to a DATE or TIMESTAMP and then back to a string in the same format then, after adding the interval, you want to use TO_CHAR to convert back to a string with the required format.
For example:
SELECT TO_CHAR(
TO_DATE(col1, 'MM/DD/RR HH24:MI') + INTERVAL '1' DAY,
'MM/DD/RR HH24:MI'
)
FROM tab1
Note: If you use YYYY in the format model then 21 will be parsed as 21 AD and not as 2021 AD. Instead, you need to use YY or RR (depending on how you want values from the end of the last century to be handled).
Please note in both the above cases format is changing.
The format of your column is not changing, you have converted the strings to DATE and TIMESTAMP which are binary data type and do not have any format.
The user interface you are using (i.e. SQL/Plus or SQL Developer) tries to be helpful and rather than presenting you, the user, with binary data will use its internal rules to format the binary data as something you can read. SQL/Plus and SQL Developer will use the NLS_DATE_FORMAT session parameter for DATE values and the NLS_TIMESTAMP_FORMAT session parameter for TIMESTAMP values. These parameters can be set to different values for each user in each of their sessions so you should not rely on them to be consistent.
If you want a consistent format then wrap the date/timestamp in TO_CHAR to apply that consistent format.
You are converting your string into a date or timestamp, and adjusting it by a day. Your client then decides how to format that for display, usually using you session setting like NLS_DATE_FORMAT.
If you want to display (or store*) the value in a particular format then you should specify that, with to_char(), e.g.:
TO_CHAR(TO_DATE(col1,'MM/DD/YYYY HH24:MI') + INTERVAL '1' DAY,'MM/DD/YYYY HH24:MI')
09/28/0021 18:05
or if you want to suppress some leading zeros to match your original string you can toggle those with the FM modifier:
TO_CHAR(TO_DATE(col1,'MM/DD/YYYY HH24:MI') + INTERVAL '1' DAY,'FMMM/DD/YYYY HH24:FMMI')
9/28/21 18:05
As you can see in the output of first of those, and as #Aitor mentioned, the year comes out as 0021 rather than 21. That's because you used a four-digit YYYY mask for a 2-digit year value. In the second one the FM suppresses that, so it's less obvious. As you don't seem to care about the century it usually doesn't matter whether you use YY or RR - the exception maybe being if you happen to hit a leap year/day; but it's still better to have the mask match the string, so with RR:
TO_CHAR(TO_DATE(col1,'MM/DD/RR HH24:MI') + INTERVAL '1' DAY,'FMMM/DD/RR HH24:FMMI')
9/28/21 18:05
db<>fiddle
* But you should not be storing dates as strings. They should be stored as dates, and formatted as strings for display only. You shouldn't really be using 2-digit years any more either.
You said your column has this: 9/27/21, but you put a mask like YYYY. Be careful with that, because with YYYY, the year will be 21 BC...
Maybe you want RRRR in your date mask. RRRR means 2-digit years in the range 00 to 49 are assumed to be in the current century:
select to_char(to_date('9/27/2021 18:05','MM/DD/RRRR HH24:MI')+ INTERVAL '1' DAY,'MM/DD/YYYY HH24:MI') result
from dual;
Result: 09/28/2021 18:05
I don't know what is your output format, but anyway, if you want your date formatted like VARCHAR, try this. With your column, is something like that
select to_char(to_date(col1,'MM/DD/RRRR HH24:MI') + 1,'MM/DD/YYYY HH24:MI') result
from your_table;
Also you can use, instead of INTERVATL '1' DAY, a simple +1

Date_Trunc and To_Date Questions SQL

Can we use date_trunc for a date (not date-time) that we are trying to "truncate" (not sure if the term can be applied here) to e.g. the start of the week? So if I have date_trunc(week, 28/10/2020) and I want to get the start of the week that 28th of October lies in (so 26th of October)? I tried this in my SQL command line but I get error messages.
If I am doing: SELECT to_date ('02 Oct 2001', 'DD Mon YYYY'); How can I ensure the resulting format is in a date format I specify (rather than the default date format)? For example if I want it in format DD-MM-YYYY?
select to_char(date '2017-06-02', 'MM') < in this example, why do we need "date" for this to work? The general format for to_char should be TO_CHAR (timestamp_expression, 'format'). I don't see in this general format that we need "day".
if I have a WHERE filter like to_char(order_date, '20-10-2020'), and there are indeed some rows with this order date, will these rows still show in my results (after running query) if these rows are in DATE format (so 20 Oct is in date format) as opposed to string (which is what I am filtering by as I am doing to_char). I know there would be no need to use to_char in this case but just asking..
yes, you can use date in text form but you have to cast it to a correct type
these queries will work
select date_trunc('week', '2020-10-28'::date);
select date_trunc('week', '10/28/2020'::date);
-- as well as
select date_trunc('week', '2020-10-28'::datetime);
and return timestamp 2020-10-26 00:00:00.000000
note, next query
select date_trunc('week', '28/10/2020'::date);
will fail with error date/time field value out of range: "28/10/2020";
You can use to_char, it returns text, if you need a date format you have to case it again
select to_char( to_date ('02 Oct 2001', 'DD Mon YYYY'), 'DD-MM-YYYY')::date;
select to_char('02 Oct 2001'::date, 'DD-MM-YYYY')::date;
'2017-06-02' is a text and it can't be automatically converted to timestamp. Actually I don't know a text format which can.
No, you need to explicitly cast into date type to use it as a filter
where order_date = date_stored_as_a_text::date
I am answering the questions in a different order as there are some wrong assumptions:
Question 3
There is a general difference between '2017-06-02' and date '2017-06-02' - the first one is just a varchar, a string, NOT handled as a date by Redshift, the 2nd one tells Redshift to handle the string as date and therefore works.
Question 2
A date data type column has no format - you may an sql client that can display date columns in different formats, however, this is not a functionality of redshift. SELECT to_date ('02 Oct 2001', 'DD Mon YYYY'); tells redshift to convert the string '02 Oct 2001' to date.
Question 1
DATE_TRUNC('datepart', timestamp) also supports week as datepart - see Date parts for date or timestamp function (Also shown in the example of AWS). You should also be able to provide a date instead of a timestamp.
Question 4
to_char(order_date, '20-10-2020')is not a filter and you are using it wrong.
AWS TO_CHAR
TO_CHAR converts a timestamp or numeric expression to a character-string data format.
I guess you are rather looking for:
where to_char(order_date, 'YYYY-MM-DD') = '20-10-2020'

ORA-01722 INVALID NUMBER in oracle

I am getting invalid number error message while executing the below select statement.Can any one have an idea about the issue..Please let me know.
select TO_DATE(TO_CHAR('2015/01/22 00:00:00','YYYY/MM/DD'),'YYYY/MM/DD')
actually i want oracle standard date format without time stamp for this date '2015/01/22 00:00:00'
select to_date('2015/01/22 00:00:00','YYYY/MM/DD HH24:MI:SS') as dt
from dual
Fiddle - http://sqlfiddle.com/#!4/6a3a6/1/0
As an FYI, the Oracle DATE data type does include the time component (just not down to fractional seconds, as is the case with the TIMESTAMP data type).
If you are converting values and want to bring all the time values to zero you can use the trunc function like this (which changes 12:07:00 to 00:00:00):
select trunc(to_date('2015/01/22 12:07:00','YYYY/MM/DD HH24:MI:SS'),'DD') as dt_with_time_zerod
from dual
Fiddle - http://sqlfiddle.com/#!4/6a3a6/2/0
If the source is itself a date and you want to convert the date to a string in the Oracle default date format ('DD-MON-RR') you can achieve that by running:
select to_char(trunc(to_date('2015/01/22 12:07:00','YYYY/MM/DD HH24:MI:SS'),'DD'),'DD-MON-RR') as dt_with_time_zerod
from dual
Fiddle - http://sqlfiddle.com/#!4/6a3a6/3/0
If it's a date field, to_char without a mask will give you what you say you want.
actually i want oracle standard date format without time stamp for this date '2015/01/22 00:00:00'
I'm not sure what you mean by "Oracle standard date format." The format in which a date would appear would be based on your NLS settings (in particular, NLS_DATE_FORMAT). If you are just trying to format this string representing a date, then you might want something like the following:
SELECT TO_CHAR(TO_DATE('2015/01/22 00:00:00','YYYY/MM/DD HH:MI:SS'), 'YYYY/MM/DD')
FROM dual;
That is, you have the TO_CHAR() and TO_DATE() functions in the wrong order, and an incomplete date mask for the call to TO_DATE().
Try using date literals with the standard ISO 8601 format.
date '2015-01-22'
I suggest you not to give hour-minute-second if you do not want to show the time.
This is my simplest answer :
SELECT TO_DATE('2015/01/22','YYYY/MM/DD') FROM dual

Questions on To_Date function

I have two questions,
1.
Why can't I get HH24:MI:SS when using To_date function?
select To_date(fn_adjusted_date(SUBMIT_DATE),'DD-MON-YY-HH24:MI:SS')
from HPD_Help_Desk;
16-NOV-08
select To_char(fn_adjusted_date(submit_date),'DD-MON-YY-HH24:MI:SS')
from HPD_Help_Desk;
16-NOV-08-06:01:10
2.
Why am I getting an error when using:
To_date(fn_adjusted_date(SUBMIT_DATE),'DD-MON-YY-HH24:MI:SS')
but changing it works fine when I change it to:
To_date(fn_adjusted_date(SUBMIT_DATE),'DD-MM-YY-HH24:MI:SS')
To demonstrate:
select sysdate from dual;
03-MAR-15
alter session set nls_date_format = 'dd-mm-yyyy hh24:mi:ss';
select sysdate from dual;
03-03-2015 11:29:22
select To_date(fn_adjusted_date(SUBMIT_DATE),'DD-MON-YY-HH24:MI:SS')
from HPD_Help_Desk;
ORA-01843: not a valid month 01843. 00000 - "not a valid month"
select To_char(fn_adjusted_date(submit_date),'DD-MON-YY-HH24:MI:SS')
from HPD_Help_Desk;
16-NOV-08-06:01:10
1.
Because to_date() gives you a date object, and you're leaving it up to your client to decide how to display that as a string; it's likely to be using your NLS_DATE_FORMAT settings.
Since your fn_adjusted_date() function returns a date not a string, do not then call to_date() on that; you're doing an implicit conversion to a string and then back to a date, both using NLS_DATE_FORMAT, and from how your first query is displayed - as DD-MON-YY? - that is losing the time portion anyway. So you're really doing:
select to_date(to_char(fn_adjusted_date(SUBMIT_DATE), 'DD-MON-YY'),
'DD-MON-YY-HH24:MI:SS') from HPD_Help_Desk;
2.
Because MON is the abbreviated month name in your date language. This follows on from the first point; now in the first of those you're doing an implicit to_char() of your value using the new NLS_DATE_FORMAT, which specifies the month number with MM, but then you try to convert that back to a date with MON. So this time you're really doing:
select to_date(to_char(fn_adjusted_date(SUBMIT_DATE), 'dd-mm-yyyy hh24:mi:ss'),
'DD-MON-YY-HH24:MI:SS') from HPD_Help_Desk;
And 11 is not a valid month name. Oracle is quite flexible with date formats when it can be; it can interpret 'NOV' using the MM model even though that doesn't make sense really since it isn't a number, but the meaning is pretty obvious; from your example in a comment:
select to_date('16-Nov-2008', 'DD-MM-YY') from dual;
TO_DATE('16-NOV-2008','DD-MM-YY')
---------------------------------
16-NOV-2008 00:00:00
It doesn't work the other way though; it can't interpret 11 using MON. That flexibility can appear inconsistent, and it sometimes seems to be too forgiving.
In the second query you're doing an explicit to_char() with a format model specified, which is the correct way to display a date as a string.
The underlying messages are the same for both: don't call to_date() when you already have a date object, don't ever rely on implicit conversion, and don't convert a date to a string while you're still processing it - only if you want it as a string in a specific format in your final result set.

Issue in removing time stamp in PL/SQL

I want to convert 12/8/2006 12:30:00 to 12/8/2006
I tried -
1. trunc(TO_DATE (effective_date_time,'DD/MM/YYYY HH24:Mi:SS'))
2. TO_DATE (effective_date_time,'DD/MM/YYYY')
But all these are returning values as 12/8/0006.
Why Oracle is returning year 0006 instead of 2006.
If effective_date_time is a date column using to_date() is totally useless.
It will first (implicitely!) convert the date to a varchar (based on the NLS settings, just to convert it back to a date again.
If you want a specific format for your date column use to_char()
to_char(effective_date_time,'DD/MM/YYYY HH24:Mi:SS')
Never use to_date() on date or timestamp columns!
Try this:
trunc(effective_date_time)
It's a date, you don't need TO_DATE
When you're using TO_DATE(effective_date_time, 'format') on a DATE column, effective_date_time is converted to a char using NLS params. I suppose your NLS settings is something like 'dd/mm/yy'. That's why you get a wrong year.
A simple example:
alter session set nls_date_format = 'dd/mm/yy';
select trunc(TO_DATE (sysdate,'DD/MM/YYYY HH24:Mi:SS')) from dual;
November, 22 0014 00:00:00+0000
alter session set nls_date_format = 'dd/mm/yyyy';
select trunc(TO_DATE (sysdate,'DD/MM/YYYY HH24:Mi:SS')) from dual;
November, 22 2014 00:00:00+0000
Your NLS_DATE_FORMAT has year as 'YY' in year.. And then you specify the format at YYYY again in to_date, so 2006, first interpretted as 06 again ended up as 0006.
Sincere advice, dont do To_DATE() on a date. Just TRUNC(yourdate) is what you need.
Try this:
trunc(effective_date_time)
Trunc will directly remove the time stamp from the date format