I tried to update a lot of rows in date format ('DD-MON-YY'). S
So, in cases such 22-FEB-99, I got 22th February 1999, instead of 22th February 2099.
Is there a way to specify the year in such cases?
I tried to update a lot of rows in date format ('DD-MON-YY').
If you have a DATE column then that is a binary data type consisting of 7 bytes (representing century, year-of-century, month, day, hour, minute and second); it ALWAYS has those components and it is NEVER stored in any (human-readable) format.
What you probably mean is that your client application (SQL Developer) is displaying the dates in the format DD-MON-RR and it is not showing you the century or time components.
Is there a way to specify the year in such cases?
Rather than letting the client application apply a default format for displaying the date, you can apply an explicit format using TO_CHAR:
SELECT TO_CHAR(your_date_column, 'FMDDth Month YYYY', 'NLS_DATE_LANGUAGE=English')
AS formatted_date
FROM your_table;
Which, for the sample data:
CREATE TABLE your_table (your_date_column) AS
SELECT SYSDATE FROM DUAL UNION ALL
SELECT DATE '2022-01-01' FROM DUAL UNION ALL
SELECT DATE '1970-01-01' FROM DUAL;
Outputs:
| FORMATTED_DATE |
|---|
| 2nd November 2022 |
| 1st January 2022 |
| 1st January 1970 |
in cases such 22-FEB-99, I got 22th February 1999, instead of 22th February 2099.
If you get the value 22th February 1999 then that is because the date is stored as 1999 and not 2099. Note: that a DATE data type always has a century component so the query will display what is stored in the column.
You have probably inserted (or updated) the date as a string:
INSERT INTO your_table (your_date_column)
VALUES('22-FEB-99');
'22-02-99' is not a date data type, it is a string literal. Oracle has tried to be helpful and implicitly convert the date to a string using the NLS_DATE_FORMAT session parameter effectively converting the query to:
INSERT INTO your_table (your_date_column)
VALUES(
TO_DATE(
'22-FEB-99',
(SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
)
);
However, your NLS_DATE_FORMAT session parameter is set to DD-MON-RR and the RR format model will convert 99 to 1999 and not 2099.
What you need to do is NEVER use implicit conversion from strings to dates; instead:
Use a date literal:
INSERT INTO your_table(your_date_column) VALUES (DATE '2099-02-22');
Use a timestamp literal (which also allows you to specify the time):
INSERT INTO your_table(your_date_column) VALUES (TIMESTAMP '2099-02-22 00:00:00');
Explicitly convert the string using TO_CHAR and the correct format model:
INSERT INTO your_table(your_date_column)
VALUES (TO_DATE('22-FEB-99', 'DD-MON-YY', 'NLS_DATE_LANGUAGE=English'));
If you have the data as 1999 and want 2099 then you will need to fix it:
UPDATE your_table
SET your_date_column = your_date_column + INTERVAL '100' YEAR(3)
WHERE your_date_column = DATE '1999-02-22';
or:
UPDATE your_table
SET your_date_column = ADD_MONTHS(your_date_column, 1200)
WHERE your_date_column = DATE '1999-02-22';
or:
UPDATE your_table
SET your_date_column = DATE '2099-02-22'
WHERE your_date_column = DATE '1999-02-22';
2-digits year is evil (does Y2K ring a bell?). You should really use 4 digits for years. Meanwhile, see whether YY vs. RR format models do any difference in your case.
(you don't have to alter the session; my database uses different date format and language so I'm setting it now)
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
SQL> alter session set nls_date_language = 'english';
Session altered.
Sample data and how yy/rr affect the result:
SQL> with test (col) as
2 (select '22-FEB-99' from dual)
3 select to_date(col, 'dd-mon-yy') val1,
4 to_date(col, 'dd-mon-rr') val2
5 from test;
VAL1 VAL2
---------- ----------
22.02.2099 22.02.1999
SQL>
'22-FEB-99'and the default format model for implicit string-to-date conversion isDD-MON-RRand the99has been converted to1999rather than the OP's expectation of2099and they need to (1) not rely on implicit conversion and (2), if they are going to use a format model, useYYrather thanRRto get the correct year. However, yes, the problem description is confusing and could be clarified with a detailed minimal reproducible example.to_date(..., 'DD-MON-YY')`, but you're probably right.