If you need to convert between Oracle date and PHP/Unix timestamp then you might need to implement two functions in Oracle.
The following two Oracle functions implement this for DATE types.
To convert a UNIX timestamp into an Oracle DATE type:
CREATE OR REPLACE
FUNCTION unixts_to_date(unixts IN PLS_INTEGER) RETURN DATE IS
/**
* Converts a UNIX timestamp into an Oracle DATE
*/
unix_epoch DATE := TO_DATE('19700101000000','YYYYMMDDHH24MISS');
max_ts PLS_INTEGER := 2145916799; -- 2938-12-31 23:59:59
min_ts PLS_INTEGER := -2114380800; -- 1903-01-01 00:00:00
oracle_date DATE;
BEGIN
IF unixts > max_ts THEN
RAISE_APPLICATION_ERROR(
-20901,
'UNIX timestamp too large for 32 bit limit'
);
ELSIF unixts < min_ts THEN
RAISE_APPLICATION_ERROR(
-20901,
'UNIX timestamp too small for 32 bit limit' );
ELSE
oracle_date := unix_epoch + NUMTODSINTERVAL(unixts, 'SECOND');
END IF;
RETURN (oracle_date);
END;
The following PHP script shows how this might be used. Note that this script requires PHP 5.x+, as it uses the new OCI extension function names:
<?php
$conn = oci_connect('scott', 'tiger');
$sql = "
SELECT
*
FROM EMP
WHERE
hiredate
BETWEEN
unixts_to_date(:startdate)
AND
unixts_to_date(:enddate)
ORDER BY
hiredate
DESC
";
$stmt = oci_parse($conn, $sql);
// Bind a UNIX timestamps to :startdate and :enddate
oci_bind_by_name($stmt, ":startdate", mktime(0,0,0,1,1,1981));
oci_bind_by_name($stmt, ":enddate", mktime(0,0,0,1,1,1990));
oci_execute($stmt);
print "NAME : HIREDATE\n";
while ( $row = oci_fetch_assoc($stmt) ) {
print "{$row['ENAME']} : {$row['HIREDATE']}\n";
}
oci_free_statement($stmt);
oci_close($conn);
?>
In reverse, the following function returns a UNIX timestamp given an Oracle DATE type:
CREATE OR REPLACE
FUNCTION date_to_unixts(oracle_date IN DATE) RETURN PLS_INTEGER IS
/**
* Converts an Oracle DATE to a UNIX timestamp
*/
unix_epoch DATE := TO_DATE('19700101000000','YYYYMMDDHH24MISS');
max_date DATE := TO_DATE('20380101000000','YYYYMMDDHH24MISS');
min_date DATE := TO_DATE('19030101000000','YYYYMMDDHH24MISS');
unix_ts PLS_INTEGER;
BEGIN
IF oracle_date > max_date THEN
RAISE_APPLICATION_ERROR( -20902,'Date too large for 32bit UNIX timestamp' );
ELSIF oracle_date < min_date THEN
RAISE_APPLICATION_ERROR( -20902,'Date too small for 32bit UNIX timestamp' );
ELSE
unix_ts := (oracle_date - unix_epoch) / (1/86400);
END IF;
RETURN (unix_ts);
END;
The following query shows how it might be used:SELECT
ename,
TO_CHAR(hiredate, 'YYYY') AS hired_year,
TO_CHAR(hiredate, 'YYYYMM') AS hired_month,
TO_CHAR(hiredate, 'ddth Mon, YYYY') AS hired_pretty
date_to_unixts(hiredate) AS hired_unixts
FROM
emp
ORDER BY
hiredate
It’s now easy to convert the timestamp into a formatted date, using the date() function as you loop through the result set.
24.94622567.04707