Link to home
Start Free TrialLog in
Avatar of DamMadsen
DamMadsen

asked on

A datepart problem!!

First of all, my English is not perfect, but i hope you guys (girls?) understand my question.

I have a field with datatype varchar where we stored dates in the format YYYY/MM/DD (ex. 2002/11/08). If the date is unknown we store 0000/00/00 and if we know only the year and month we store YYYY/MM/32.
The reason for storing the date in this format is that we the system originally was build for another database-system.

And this system works fine, but if I want to use datepart to convert the date to week it is only possible if the date is "valid" otherwise it returns an error.

EX.
SELECT datepart(wk, '2001/07/10') returns 28
SELECT datepart(wk, '2001/07/32') return error
"The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value."

Likewise some of our dates are "wrong" ex. 2001/09/31 which of cause don't exists since there is only 30 days in september
SELECT datepart(wk, '2001/09/31') return error
"The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value."


Oki, then what i want to know is if it is possible to "ignore" the error. When i run statement that return ex. 100 rows with datepart(wk, date_field) the whole statement doesn't run if only one of the dates is not valid?

So i want it to continue the statement and ignore the date-errors og maybe there are en entirely different way to do it?

Hope you understand my English og of cause my problem.


Avatar of Guy Hengel [angelIII / a3]
Guy Hengel [angelIII / a3]
Flag of Luxembourg image

use a REPLACE function to change the 32 to some other value, likewise 01:
SELECT datepart(wk, REPLACE( '2001/07/32' , '/32', '/01' )

Unfortunately, you cannot "ignore" this error, you must "filter" out or modify these values to have a valid transformation in 100% of the cases...

CHeers
Avatar of hans_vd
hans_vd

Maybe try this:

select case when isdate('2001/07/32') = 1 then datepart(wk, '2001/07/32') else 0 end as weekValue1

ASKER CERTIFIED SOLUTION
Avatar of Flynnious
Flynnious

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This might help get you started on checking every possoble part of your date to see if it is valid.

Copy it into Query Analyzer And Execute

ADW

DECLARE @date   VARCHAR(10)
SELECT @date = '2004/02/29'

IF ISDATE(@date) = 1
BEGIN   --This is a valid Year, Month, Day
   PRINT   'Valid Year/Month/Day'
END
ELSE IF ISDATE((REVERSE(SUBSTRING(REVERSE(@date), PATINDEX('%/%', REVERSE(@date)), LEN(@date))) + '01')) = 1
BEGIN   --This is a valid Year and Month
   PRINT   'Valid Year/Month Only'
END
ELSE IF ISDATE(LEFT(@date, PATINDEX('%/%', @date)) + '01' + RIGHT(@date, PATINDEX('%/%', REVERSE(@date)))) = 1
BEGIN   --This is a valid Year and Day only
   PRINT   'Valid Yeay and Day Only'
END
ELSE IF ISDATE(LEFT(@date, PATINDEX('%/%', @date) - 1) + '/01/01') = 1
BEGIN   --This is a valid year only
   PRINT   'Valid Year Only'
END
ELSE IF ISDATE('2000/' + RIGHT(@date, LEN(@date) - PATINDEX('%/%', @date))) = 1
BEGIN   --This is a valid month/day only
   PRINT   'Valid Month/Day Only'
END
ELSE IF ISDATE('2000/01' + RIGHT(@date, PATINDEX('%/%', REVERSE(@date)))) = 1
BEGIN   --This is a valid day only
   PRINT   'Valid Day Only'
END
ELSE IF ISDATE('2000/' + LEFT(RIGHT(@date, LEN(@date) - PATINDEX('%/%', @date)), PATINDEX('%/%', RIGHT(@date, LEN(@date) - PATINDEX('%/%', @date)))) + '01') = 1
BEGIN   --This is a valid Month only
   PRINT   'Valid Month Only'
END
ELSE
BEGIN
   PRINT   'Not a Valid Year, Month, Or Day'
END
I agree that there is no way to ignore the error.  But since you know what data errors will occur, you could code to handle them with appropriate checks.  For example:

DECLARE @maxDaysInMth VARCHAR(25)
SET @maxDaysInMth = ' 312831303130313130313031'

SELECT CASE
WHEN SUBSTRING(yourDate, 9, 2) > SUBSTRING(@maxDaysInMth, CAST(SUBSTRING(yourDate, 6, 2) AS INT) * 2, 2)
THEN DATEPART(WEEK, LEFT(yourDate, 8) + SUBSTRING(@maxDaysInMth, CAST(SUBSTRING(yourDate, 6, 2) AS INT) * 2, 2))
ELSE DATEPART(WEEK, yourDate)
END
FROM yourTable
WHERE yourDate <> '0000/00/00'

This code checks if the day is greater than the max allowed for that month; if so, it changes it to the max.

You would of course have to add code to handle leap years, if desired.
Avatar of DamMadsen

ASKER

In fact all the answers where very usable and thanks alot, but found the most help in this answer.