views:

552

answers:

10

What can bite me if I store a datetime as a float in the database? I have a very good reason for doing it so don't complain about that :)

Edit: I was thinking about just storing convert(float, @thedate) in a float column.

+1  A: 

Precision loss for one. Lack of resolution is another.

Its a minor issue, but floating point versions IEEE 754 vs VAX Floating Point.

Alan
But notice that you can calculate this: For examples an 8 byte int (or float) is enough to store 584000 years in microsecond precision (256**8 / 1.000.000 / 60 / 60 / 24 / 365).
schnaader
A: 

If you're going to store that data as a float, I think you'd be better off storing seconds since epoch as a float than datetime as a float

Jiaaro
+1  A: 

SQLite uses a time format (one of a few available) with a (64 bit) double float using the integer part for days since an epoch, and the fractional part as fraction of a day. It seems to work well.

See SQLite Date and Time Functions "Format 12 is the Julian day number expressed as a floating point value."

Using Julian Dates 15 decimal digits gets you millisecond precision for several millennia.

According to this Julian Date Converter, JD 9999999.99999 is CE 22666 December 20 11:59:59.1 UT Thursday

Doug Currie
+4  A: 

What Alan said, plus... the fundamental problem of maintenance; when someone else comes onto the project, and sees the float for datetime in the DB, and tries to do something wrong with it, or tries to refactor it to the proper type, or just spends hours poring over the code to figure out what the heck is going on. The whole problem of maintenance can to some extent be mitigated by extensively documenting what's going on and why you're doing it, which I'd recommend highly.

McWafflestix
I'm willing to take the maintenance problem. As I said, I have a very good reason for doing it.
erikkallen
I'm not saying you shouldn't do it (although I probably should); it's your choice; I'm just answering the question as to what can bite you. At the very least, I'd recommend documenting the hell out of why you're doing this as a means to mitigate the maintenance problem.
McWafflestix
A: 

Actually, as far as I know, MSSQL and Oracle actually do internally store datetimes as floats (as day and fractional days)

select cast(0 as datetime), cast(0.5 as datetime)
1900-01-01 00:00:00.000 1900-01-01 12:00:00.000
James Curran
This doesn't prove that dates are stored as floats, it only proves they have an float->day translation on casting
Tom Leys
A: 

Regardless of precision - depending on what number you choose as a start point, you may have trouble with comparisons.

If you are unable to create precise floats for each datetime, you may also have have two datetimes that compare both one way and the other if they resolve to different floats.

tehblanx
+1  A: 

You lose some precision. I tested in SQL Server with:

select getdate(), cast(getdate() as float), cast(cast(getdate() as float) as datetime)

You can see if you run this repeatedly that you can lose as much as 4 milliseconds in the conversion. If your database supports a data type like smalldatetime and you only need accuracy to the second, then you can smooth out this difference.

RedFilter
you should do that with a static date.
dotjoe
--here's a good example...declare @d datetime;set @d = '2009-05-27 16:33:54.260'select @d, cast(cast(@d as float) as datetime), cast(cast(cast(cast(@d as float) as datetime) as float) as datetime)
dotjoe
That is effectively a static date, you will never get different dates returned using getdate() in one statement.
RedFilter
+4  A: 

Here is a good article on "Demystifying the SQL Server DATETIME Datatype"

http://www.sql-server-performance.com/articles/dev/datetime_datatype_p1.aspx

From reading that, it looks like datetime is stored as 2 4-byte ints or you could use binary(8)

as others have said, storing as a float causes you to lose some precision.

Jon Erickson
+6  A: 

What can bite you? Well first float is not an exact datatype and thus should probably never be used for anything that requires precision. Next, float will not automatically reject an incorrect date. Next, if you want to perform any date functions you will first have to convert the data back to a datetime data type which is a waste of server resources.

You say you have a good reason for wanting to do this, but with a clue as to what that might be, I submit that the dates should be stored in the datatype meant to handle them.

HLGEM
+1 for "float will not automatically reject an incorrect date."
RedFilter
If the float is a Julian Date, for example, there is no "incorrect date," just finer resolutions or greater range of time.
Doug Currie
Example: select cast(cast(2958464 as float) as datetime)
RedFilter
(for SQL Server, this gives "Arithmetic overflow error converting expression to data type datetime.")
RedFilter
Well, that's a limitation of the SQLServer implementation, not the format itself.
Doug Currie
A: 

A potential disadvantage of using a float would be that you lose the ability to use the system's built-in date manipulation functions. If you're only doing interval calculations, floating-point may be fine, but anything relating to calendars could require some wheel-reinventing.

BTW, it seems Oracle at least uses fixed fields for its internal date representation:

select
  to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') as Date_Value,
  dump(sysdate) as Internals
from dual;

DATE_VALUE          INTERNALS                                                   
------------------- ------------------------------------------------------------
2009-05-28 09:51:12 Typ=13 Len=8: 217,7,5,28,9,51,12,0                          
1 row selected
cheduardo