#sql #oracle #oracle12c #date-conversion
#sql #Oracle
Вопрос:
Мне нужно преобразовать дату из текстового поля из даты в эпоху, чтобы я мог вставить ее в Oracle DB.
Мне удалось преобразовать из эпохи в дату, как показано ниже, но я не смог найти способ преобразовать его другим способом.
SelectCommand="SELECT ID,
COMPANY,
FIRST_NAME,
LAST_NAME,
ID_NUMBER,
(SELECT TO_CHAR(TO_DATE('01-JAN-1970','DD/MM/YYYY')
(TRAINING_DATE/60/60/24), 'MM/DD/YYYY') FROM dual) AS TRAINING_DATE,
(SELECT TO_CHAR(TO_DATE('01-JAN-1970','DD/MM/YYYY')
(TRAINING_VALABILITY/60/60/24),'MM/DD/YYYY') FROM dual) AS TRAINING_VALABILITY
FROM CONTRACTORS
ORDER BY COMPANY"
Комментарии:
1. Вы уверены, что хотите (или должны) хранить время эпохи в базе данных Oracle? Почему бы не сохранить фактическую дату? Пусть ваши приложения преобразуют его в эпоху времени, если / когда это необходимо.
2. Не пишите
(SELECT TO_CHAR(TO_DATE('01-JAN-1970','DD/MM/YYYY') (TRAINING_DATE/60/60/24), 'MM/DD/YYYY') FROM dual) AS TRAINING_DATE
, просто сделайтеTO_CHAR(TO_DATE('01-JAN-1970','DD/MM/YYYY') (TRAINING_DATE/60/60/24), 'MM/DD/YYYY') AS TRAINING_DATE
3. Обратите внимание на свой местный часовой пояс. Эпоха Unix — 1970-01-01 00:00:00 UTC!
4. Как ни странно, этот ваш код работает, несмотря на намеренное использование неправильной маски формата! :
TO_DATE('01-JAN-1970','DD/MM/YYYY')
. Однако самым удобным способом записи буквальной даты является формат ANSI :DATE '1970-01-01'
.5. Вы не можете добавить 2 даты, как есть, хотя вы можете их вычесть .
Ответ №1:
Вычитание DATE '1970-01-01'
из значения даст разницу в количестве дней (и дробных часов / минут / секунд), а затем вы можете умножить на 24*60*60
:
(date_value - DATE '1970-01-01')*24*60*60
Обновить:
Обычно время эпохи измеряется от 1970-01-01T00:00:00 UTC
. Если ваша дата не указана в UTC, вам нужно будет преобразовать часовые пояса.
Например, если ваша дата имеет часовой пояс Europe/Berlin
:
( CAST(
FROM_TZ(
CAST( date_value AS TIMESTAMP ), -- Cast to timestamp
'Europe/Berlin' -- Convert to expected Time Zone
)
AT TIME ZONE 'UTC' -- Convert Time Zone to UTC
AS DATE -- Cast back to DATE data type
)
- DATE '1970-01-01'
)*24*60*60
Комментарии:
1. Вот пример использования приведенного выше метода:
select (TO_DATE('02-01-2018', 'MM-DD-YYYY') - TO_DATE('01-JAN-1970','DD/MM/YYYY'))*24*60*60 from dual;
Ответ №2:
UpdateCommand="UPDATE CONTRACTORS
SET COMPANY=:COMPANY,
FIRST_NAME=:FIRST_NAME,
LAST_NAME=:LAST_NAME,
ID_NUMBER=:ID_NUMBER,
TRAINING_DATE=(TO_DATE(:TRAINING_DATE, 'MM-DD-YYYY HH24:MI:SS') - TO_DATE('01-JAN-1970','DD/MM/YYYY'))*24*60*60,
TRAINING_VALABILITY=(TO_DATE(:TRAINING_VALABILITY, 'MM-DD-YY`enter code here`YY HH24:MI:SS') - TO_DATE('01-JAN-1970','DD/MM/YYYY'))*24*60*60
WHERE (ID=:ID)"
Ответ №3:
Я использую это решение, которое работает правильно, независимо от того, вводится ли дата по местному времени в летнее время (DST) или нет.
SELECT Round((Cast(Sys_extract_utc( Cast( your_date_field AS TIMESTAMP )) AS DATE) - To_date('1970-01-01','YYYY-MM-DD HH24MISS')) *24*60*60) AS epoch FROM dual;
-- 'your_date_field'
-- '20210112' -> 1610427600 (no DST)
-- '20210512' -> 1620792000 (DST)