Come ha detto @Gordon, i timestamp (e le date) non sono archiviati in un formato che riconosceresti Oracle utilizza una rappresentazione interna di cui non hai mai davvero bisogno di conoscere o esaminare (ma è documentato se sei interessato a quel genere di cose) .
Quando esegui una query su un timestamp, viene visualizzato utilizzando le impostazioni NLS del tuo client, a meno che tu non abbia un client che le sovrascrive. Posso impostare la mia sessione in modo che corrisponda a ciò che stai vedendo:
alter session set nls_timestamp_format = 'DD-MON-RR HH.MI.SS.FF AM';
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 15:37:31
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 03.37.31.000000000 PM
E posso cambiarlo per vedere cosa vuoi vedere:
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS';
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHA
-------------------
2018-07-10 15:37:32
Ma tutto ciò che stai facendo è convertire da un timestamp con fuso orario (che è ciò che systimestamp
is) a una stringa e poi di nuovo a un timestamp. Stai perdendo la parte del fuso orario e qualsiasi frazione di secondo; cosa che potresti fare anche con un cast
:
select cast(systimestamp as timestamp(0)) from dual;
CAST(SYSTIMESTAMPAS
-------------------
2018-07-10 15:37:32
Puoi vedere il fuso orario e la frazione di secondo con il tuo timestamp_tz
predefinito formato:
select systimestamp from dual;
SYSTIMESTAMP
------------------------------------
2018-07-10 15:37:33.776469000 +01:00
e cambialo con un diverso alter
:
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS.FF3 TZH:TZM';
select systimestamp from dual;
SYSTIMESTAMP
------------------------------
2018-07-10 15:37:34.070 +01:00
Il che non è del tutto rilevante se stai davvero parlando di memorizzare i timestamp in una tabella, ma mostra che ci sono variazioni.
Nella tua tabella crea il tipo di dati timestamp
(o timestamp with time zone
o timestamp with local time zone
), e preoccuparti solo di formattare il valore come stringa per la presentazione all'utente finale, all'ultimo momento possibile.
Quando hai bisogno di visualizzarlo, se il formato di visualizzazione è importante per te, usa to_char()
con una maschera di formato esplicito:non dare per scontato che nessun altro che esegue le tue query abbia le stesse impostazioni NLS. Come puoi vedere, è facile cambiarli per modificare l'output. (La maggior parte dei client ha un modo per farti impostare le impostazioni predefinite in modo da non dover fare lo stesso alter
comandi ogni volta che ti connetti; per esempio. in SQL Developer, da Strumenti->Preferenze->Database->NLS). Se vuoi mostrare sempre lo stesso formato, usa qualcosa come:
select to_char(your_column, 'YYYY-MM-DD HH24:MI:SS') as column_alias
from your_table
where your_column < timestamp '2018-01-01 00:00:00'
che mostra anche il valore della colonna che viene filtrato (come timestamp ancora) utilizzando un valore letterale di timestamp.