Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Valid Date Checks in Oracle

Tags:

date

oracle

I have a date value (either valid date or invalid date) store in varchar format. Is it possible to check the date is valid or not in sql query.

like image 371
vvekselva Avatar asked Feb 05 '13 07:02

vvekselva


People also ask

How do you check if a date is valid?

Given date in format date, month and year in integer. The task is to find whether the date is possible on not. Valid date should range from 1/1/1800 – 31/12/9999 the dates beyond these are invalid. These dates would not only contains range of year but also all the constraints related to a calendar date.

How do I check if a date is valid in SQL?

SQL Server ISDATE() Function The ISDATE() function checks an expression and returns 1 if it is a valid date, otherwise 0.

Is date function in Oracle?

Date functions in Oracle can be defined as a set of functions which operate on date and allows the developer or users to retrieve the current date and time in a particular time zone or extract only the date/ month/year or more complex actions like extracting the last day of the month/ next day/ session time zone and it ...


4 Answers

Yes, if you know the format and with little plsql.

Let's say you have the date in format 'yyyy-mon-dd hh24:mi:ss'.

create function test_date(d varchar2) return varchar2
is
  v_date date;
begin
  select to_date(d,'yyyy-mon-dd hh24:mi:ss') into v_date from dual;
  return 'Valid';
  exception when others then return 'Invalid';
end;

Now you can:

select your_date_col, test_date(your_date_col)
from your_table;
like image 132
Florin stands with Ukraine Avatar answered Nov 30 '22 13:11

Florin stands with Ukraine


You can do it in a block like

BEGIN
  select TO_DATE(your_date,'YYYYMMDD') from dual; --ADD INTO V_DUMMY IN PLSQL
EXCEPTION WHEN OTHERS THEN dbms_output.put_line('NOT A VALID DATE');
END;
like image 45
Canburak Tümer Avatar answered Nov 30 '22 12:11

Canburak Tümer


Without using block or creating custom functions or procedures, you can use just the select statement below so it returns the true date value parsed from the date string and returns null if the date string cannot be recognized.

This approach has limitation. Please see notes below.

select
  case
    when regexp_substr(DateStr,'^[[:digit:]]{2}-[[:digit:]]{2}-[[:digit:]]{4}$') is not null then
      case
        when to_number(regexp_substr(DateStr,'[^-]+',1,1))<=12 and to_number(regexp_substr(DateStr,'[^-]+',1,2))<=31
        then add_months(to_date('01-01-1900','MM-DD-YYYY'),(to_number(regexp_substr(DateStr,'[^-]+',1,3))-1900)*12+to_number(regexp_substr(DateStr,'[^-]+',1,1))-1)+to_number(regexp_substr(DateStr,'[^-]+',1,2))-1
        else null
      end
    else null
  end RealDateVal
from MyTable

This example takes date format as "MM-DD-YYYY", and assumes "MyTable" to have the date string column "DateStr". You may have to adjust accordingly for you need.

The overall approach is to first check the date string to be in the format ??-??-???? where a "?" is a digit, and then check the first ?? to be no larger than 12 (for the month) and the second ?? to be no larger than 31 (for the date). If all pass, then to assembly a date-typed value by using the "add_months()" function to build the year and month, and using the "+" function to build the date. If any of these criteria is not satisfied, then to return null.

Note 1: As we have no simple way to check if a year has Feb-29th and I am lazy in checking if a month has the 31st, a day presented as an invalid 29th, 30th or 31st, that would not be caught by the validity check, will be pushed to the next month. (See examples below.) And the query will never return an error.

Note 2: "case when ... is not null then ... else ... end" is lazy, so it won't evaluate the "then ..." part to potentially trigger error, in the case if "when ... is not null" is not satisfied. This feature is fundamental to the overall approach. Instead, the function nvl2() is not lazy and cannot be used instead.

Examples:
'06-15-2015' -> returns valid date
'06-15-2015 ' -> returns null
'06/15/2015' -> returns null
'15-06-2015' -> returns null
'06-31-2015' -> return valid date as 07-01-2015
'02-30-2015' -> return valid date as 03-02-2015

Go further: Depending on how far you want to go, you can mitigate the limitation exhibited in "Note 1" by converting the parsed date value back into string and compare it with the original date string value.

like image 23
Adrian Huang Avatar answered Nov 30 '22 12:11

Adrian Huang


Just use to_date function to check wether the date is valid/invalid.

BEGIN
  select TO_DATE(your_date,DateFormat) from dual;
EXCEPTION WHEN OTHERS THEN dbms_output.put_line('NOT A VALID DATE');
END;
like image 21
user2001117 Avatar answered Nov 30 '22 11:11

user2001117