Reputation: 539
I am trying to convert decimal value to date in select statement
SELECT user_id, extend(dbinfo("UTC_TO_DATETIME",min(creationdate)), year to fraction) AS earned_date
FROM message
But I am getting this error
Value exceeds limit of INTEGER precision
The field definition in table is this
creationDate decimal(14,0) NOT NULL
It seems I am not using the right way to do the conversion, any idea?
Upvotes: 3
Views: 4988
Reputation: 9188
I don't think you need to use EXTEND
in this context - EXTEND
is used to change the scale of DATETIME and INTERVAL values.
UTC_TO_DATETIME
returns a DATETIME value already.
Have you tried:
SELECT user_id, dbinfo("UTC_TO_DATETIME",min(creationdate)) AS earned_date
FROM message
What does that produce?
UPDATE
Ahh, an example makes all the difference!
The value you are passing is not a UTC datetime as UTC_TO_DATETIME
expects. The function expects an integer representing seconds, not milliseconds. It's as simple as that.
DBINFO('UTC_TO_DATETIME', 1329994172574)
exceeds integer precision.
DBINFO('UTC_TO_DATETIME', 1329994172574/1000)
on the other hand, produces:
2012-02-23 21:49:32
, which I guess is what you expect?
If you have a look at the link I provided earlier, it explains treatment of fractional seconds. (Spoiler: they're ignored.)
If the fractional seconds are critically important, I guess you're going to have to EXTEND
the results of this function to fractional seconds, and then add MOD(creationdate,1000)/1000 to it.
For example:
SELECT user_id,
(dbinfo("UTC_TO_DATETIME", MIN(creationdate)/1000 )::DATETIME YEAR TO FRACTION(3)
+ (MOD(MIN(creationdate),1000)/1000) UNITS FRACTION) AS earned_date
FROM message
(But personally, I would be inclined to put this logic into an SPL anyway, so you could call it like:
SELECT user_id, millis_to_time(MIN(creationdate))...
and avoid writing this sort of complex algorithm all over the place.)
Upvotes: 3
Reputation: 539
I managed to write a stored procedure for this, it seems the only solution? The decimal (14) is in milliseconds, so here is the solution
create procedure "informix".millis_to_time(milli_val decimal(14,0)) returning datetime year to fraction(3);
define retval datetime year to fraction(3);
define num_days int;
define num_seconds int;
define millis_in_day int;
let millis_in_day = 86400000;
let num_days = trunc(milli_val/millis_in_day,0);
let num_seconds = (milli_val - (num_days * millis_in_day))/1000;
let retval = extend(mdy(1,1,1970), year to fraction(3));
let retval = retval + num_days units day;
let retval = retval + num_seconds units second;
return retval;
end procedure;
Upvotes: 1
Reputation: 129
Try like this,
select
DT,
DT_Date = convert(datetime,convert(varchar(8),left(dt,8)))
from
( -- Test data
select DT = 19001231.000000
) a
Here, DT = 19001231
First 4 Digits (1900) - Year, Next 2 Digits (12) - Month, Last 2 Digits (31) - Date.
It should be similar to the above format then only you can convert. Hope it helps you, Thank You.
Upvotes: 1