Что я делаю не так?
Функция TO_DATE
имеет подпись:
TO_DATE( date_string, format_model, nls_param )
Где все аргументы ожидается, что будет иметь строковый тип данных.
Вы не передаете строку в качестве первого аргумента; вы передаете тип данных DATE
. Oracle попытается помочь вам и преобразует DATE
, который вы передаете, в строку, неявно вызывая TO_CHAR
, используя параметр сеанса формата даты текущего сеанса NLS.
Итак, ваша функция эффективна:
create or replace function date_to_epoch(
date_in in date
) return number
is
epoch_out number;
begin
epoch_out := round(
( to_date(
TO_CHAR(
date_in,
( SELECT value
FROM NLS_SESSION_PARAMETERS
WHERE parameter = 'NLS_DATE_FORMAT' )
),
'yyyy-mm-dd hh24:mi:ss'
)
-
to_date(
'1970-01-01',
'yyyy-mm-dd'
)
)*24*60*60
);
return epoch_out;
end;
Чтобы исправить это, вам нужно просто использовать ввод даты в качестве даты, а не пытаться преобразовать то, что уже является датой, в дату:
CREATE FUNCTION date_to_epoch(
date_in IN DATE
) RETURN NUMBER DETERMINISTIC
IS
BEGIN
RETURN ROUND( ( date_in - DATE '1970-01-01' )*24*60*60 );
END date_to_epoch;
Однако вы также необходимо убедиться, что ваши даты находятся в часовом поясе UT C и если они не конвертированы в UT C, перед вычислением эпохи:
CREATE FUNCTION date_to_epoch(
date_in IN DATE,
timezone IN VARCHAR2 DEFAULT 'UTC'
) RETURN NUMBER DETERMINISTIC
IS
BEGIN
RETURN ROUND(
( CAST(
FROM_TZ( date_in, timezone ) -- Convert to a timestamp in the correct TZ
AT TIME ZONE 'UTC' -- Change to the UTC TZ
AS DATE -- Cast back to a date
)
- DATE '1970-01-01'
)*24*60*60
);
END date_to_epoch;
/
Итак:
SELECT date_to_epoch( DATE '1970-01-01' ) AS utc_epoch,
date_to_epoch( DATE '1970-01-01', 'PST' ) AS pst_epoch
FROM DUAL;
выходы:
UTC_EPOCH | PST_EPOCH
--------: | --------:
0 | 28800
дБ <> скрипка здесь