June 8, 2010 at 11:27 am
Hi All,
I was looking at a certain issue and saw that the same cast with convert function gives me two dates when it should be one date. 54 sec difference between the two dates.
select cast((convert(varchar(10), cast('2010-03-12 23:59:58.047' as smalldatetime), 101)) as datetime)
GO
select cast((convert(varchar(10), cast('2010-03-12 23:59:04.047' as smalldatetime), 101)) as datetime)
GO
The first one gives an output of 2010-03-13 00:00:00.000 but the second one gives an output as 2010-03-12 00:00:00.000.
Has anyone seen this behavior?
We usually use SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, '2010-03-12 23:59:58.047')) but there are legacy SP's that still use the CAST and Convert.
-Roy
June 8, 2010 at 11:41 am
Roy it looks to me that this is a rounding issue when the convert is changing to smalldatetime; that is wierd to me as well, since i'd expect the rounding to not be affected at the per-second level;
the breakpoint is anything above 2010-03-12 23:59:30.000 is rounded up to the next smalldatetime;
take a look at the results of this:
declare @results table(TheFullDate datetime,TheSmallDate smalldatetime)
declare @TheDate datetime
set @TheDate = '2010-03-12 23:59:00.000' --or '2010-03-12 23:59:00.047'
while @TheDate < '2010-03-14 00:00:00.000'
BEGIN
insert into @results
select @TheDate,cast((convert(varchar(10), cast(@TheDate as smalldatetime), 101)) as datetime)
SELECT @TheDate = dateadd(ss,1,@TheDate)
END
select * from @results
Lowell
June 8, 2010 at 11:41 am
Hi Roy,
From what I can see, the casting to smallDatetime seems to be the problem. It has an accuracy of 1 minute, therefore, it does round the 57 seconds to the next minute, and then falls on the next day. Taking the 10 first characters to convert to a datetime is the reason you have the wrong day.
What is the behavior you were expecting from this, do you want to use the current day?
Cheers,
J-F
June 8, 2010 at 12:01 pm
Hi Lowell,
It is very strange that the rounding is done on second basis. That is what bothered me as well. You would not think that it would happen.
J-F, We have date field along with datetime and when we need to join the two tables based on the date, we usually use DATEADD(dd, 0, DATEDIFF(dd, 0, a.colname)) = b.ColName for example. But there are some legacy stored procs we still need to change and it was using the above mentioned method. Once in whole we would see mismatch in the volume since the currency rate could vary a lot from one day to another.
-Roy
June 8, 2010 at 2:32 pm
Lowell already pointed out where the rounding point happens. But, just as an FYI, BOL says (where ss means Seconds):
ss is two digits, ranging from 00 to 59, that represent the second. Values that are 29.998 seconds or less are rounded down to the nearest minute, Values of 29.999 seconds or more are rounded up to the nearest minute.
Cheers!
June 8, 2010 at 4:04 pm
Just to confirm... SMALLDATETIME rounds at the 30 second mark. In the last 30 seconds of a given day, it will round up to the next minute which is actually the first minute of the next day.
The general rule would be... don't use CONVERT to do datetime math. Use the DATEADD/DATEDIFF method.
--Jeff Moden
Change is inevitable... Change for the better is not.
June 9, 2010 at 6:30 am
Hi Jeff,
That is what we use but we have some legacy stuff that used these converts. We are changing them all of them.
-Roy
June 9, 2010 at 6:49 am
Hi Roy,
Heh... I had to laugh a bit because I'm right there with you. Seems the phrase "legacy code" usually means "problem code"... even if it was us that wrote it ten years ago. 😛
--Jeff Moden
Change is inevitable... Change for the better is not.
June 9, 2010 at 7:16 am
Jeff,
Yes, half of it was written after I joined this company... 🙂 I have done some sloppy work as well... hehehe
But I am learning. We started the habit (rule) of reviewing all code that goes to production DB only 3 yrs back. Till then it was Free for all with developers having access to production DB. Those were the days when I was called in almost every weekend to fix cra* that was broken... 😀
-Roy
Viewing 9 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic. Login to reply