Преобразование из даты в эпоху-Oracle

#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
  

db<>скрипка

Комментарии:

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)