Sök…


Genererar datum med ingen tidskomponent

Alla DATE har en tidskomponent; emellertid är det vanligt att lagra datum som inte behöver inkludera tidsinformation med timmar / minuter / sekunder inställda på noll (dvs. midnatt).

Använd en ANSI DATE bokstav (med ISO 8601-datumformat ):

SELECT DATE '2000-01-01' FROM DUAL;

Konvertera den från en TO_DATE() med TO_DATE() :

SELECT TO_DATE( '2001-01-01', 'YYYY-MM-DD' ) FROM DUAL;

(Mer information om datumformatmodeller finns i Oracle-dokumentationen.)

eller:

SELECT TO_DATE(
         'January 1, 2000, 00:00 A.M.',
         'Month dd, YYYY, HH12:MI A.M.',
         'NLS_DATE_LANGUAGE = American'
       )
FROM   DUAL;

(Om du konverterar språkspecifika termer som månadsnamn är det bra att inkludera den tredje nlsparam parametern till TO_DATE() -funktionen och ange vilket språk som ska förväntas.)

Generera datum med en tidskomponent

Konvertera den från en TO_DATE() med TO_DATE() :

SELECT TO_DATE( '2000-01-01 12:00:00', 'YYYY-MM-DD HH24:MI:SS' ) FROM DUAL;

Eller använd en TIMESTAMP bokstav :

CREATE TABLE date_table(
  date_value DATE
);

INSERT INTO date_table ( date_value ) VALUES ( TIMESTAMP '2000-01-01 12:00:00' );

Oracle kastar implicit en TIMESTAMP till en DATE när den lagras i en DATE kolumn i en tabell; Du kan dock uttryckligen CAST() värdet till en DATE :

SELECT CAST( TIMESTAMP '2000-01-01 12:00:00' AS DATE ) FROM DUAL;

Datum för format

I Oracle har en DATE datatyp inget format; när Oracle skickar en DATE till klientprogrammet (SQL / Plus, SQL / Developer, padda, Java, Python, etc.) kommer det att skickas 7- eller 8- byte som representerar datumet.

En DATE som inte lagras i en tabell (dvs. genereras av SYSDATE och har "typ 13" när du använder DUMP() ) har 8-byte och har strukturen (siffrorna till höger är den interna representationen för 2012-11-26 16:41:09 ):

BYTE VALUE                           EXAMPLE
---- ------------------------------- --------------------------------------
1    Year modulo 256                 220
2    Year multiples of 256           7   (7 * 256 + 220 = 2012)
3    Month                           11
4    Day                             26
5    Hours                           16
6    Minutes                         41
7    Seconds                         9
8    Unused                          0

En DATE som lagras i en tabell ("typ 12" när du använder DUMP() ) har 7-byte och har strukturen (siffrorna till höger är den interna representationen för 2012-11-26 16:41:09 ):

BYTE VALUE                           EXAMPLE
---- ------------------------------- --------------------------------------
1    ( Year multiples of 100 ) + 100 120
2    ( Year modulo 100 ) + 100       112 ((120-100)*100 + (112-100) = 2012)
3    Month                           11
4    Day                             26
5    Hours + 1                       17
6    Minutes + 1                     42
7    Seconds + 1                     10

Om du vill att datumet ska ha ett specifikt format måste du konvertera det till något som har ett format (dvs. en sträng). SQL-klienten kan implicit göra detta eller så kan du uttryckligen konvertera värdet till en sträng med TO_CHAR( date, format_model, nls_params ) .

Konvertera datum till en sträng

Använd TO_CHAR( date [, format_model [, nls_params]] ) :

(Observera: om en formatmodell inte tillhandahålls så används NLS_DATE_FORMAT sessionsparametern som standardformatmodell . Det kan vara annorlunda för varje session så bör inte lita på. Det är bra att alltid ange formatmodellen.)

CREATE TABLE table_name (
  date_value DATE
);

INSERT INTO table_name ( date_value ) VALUES ( DATE '2000-01-01' );
INSERT INTO table_name ( date_value ) VALUES ( TIMESTAMP '2016-07-21 08:00:00' );
INSERT INTO table_name ( date_value ) VALUES ( SYSDATE );

Sedan:

SELECT TO_CHAR( date_value, 'YYYY-MM-DD' ) AS formatted_date FROM table_name;

utgångar:

FORMATTED_DATE
--------------
2000-01-01
2016-07-21
2016-07-21

Och:

SELECT TO_CHAR(
         date_value,
         'FMMonth d yyyy, hh12:mi:ss AM',
         'NLS_DATE_LANGUAGE = French'
       ) AS formatted_date
FROM   table_name;

utgångar:

FORMATTED_DATE
-----------------------------
Janvier   01 2000, 12:00:00 AM
Juillet   21 2016, 08:00:00 AM
Juillet   21 2016, 19:08:31 PM

Ställa in standardmodellen för datumformat

När Oracle underförstått konverterar från en DATE till en sträng eller vice versa (eller när TO_CHAR() eller TO_DATE() kallas uttryckligen utan en NLS_DATE_FORMAT ) kommer NLS_DATE_FORMAT att användas som formatmodell i konverteringen. Om det bokstavliga inte stämmer med formatmodellen kommer ett undantag att tas upp.

Du kan granska denna parameter med:

SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT';

Du kan ställa in detta värde inom din nuvarande session med:

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

(Obs: detta ändrar inte värdet för andra användare.)

Om du litar på NLS_DATE_FORMAT att tillhandahålla TO_DATE() i TO_DATE() eller TO_CHAR() bör du inte bli förvånad när dina frågor bryts om detta värde någonsin ändras.

Ändra hur SQL / Plus eller SQL Developer visar datum

När SQL / Plus eller SQL Developer visar datum kommer de att utföra en implicit konvertering till en sträng med standarddatumformatmodellen (se Ställa in standarddatamodellmodellen ).

Du kan ändra hur ett datum visas genom att ändra NLS_DATE_FORMAT parametern.

Datum aritmetik - Skillnad mellan datum i dagar, timmar, minuter och / eller sekunder

I oracle kan skillnaden (i dagar och / eller fraktioner därav) mellan två DATE hittas med hjälp av subtraktion:

SELECT DATE '2016-03-23' - DATE '2015-12-25' AS difference FROM DUAL;

Visar antalet dagar mellan de två datumen:

DIFFERENCE
----------
        89

Och:

SELECT TO_DATE( '2016-01-02 01:01:12', 'YYYY-MM-DD HH24:MI:SS' )
         - TO_DATE( '2016-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS' )
         AS difference
FROM   DUAL

Visar fraktionen av dagar mellan två datum:

DIFFERENCE
----------
    1.0425

Skillnaden i timmar, minuter eller sekunder kan hittas genom att multiplicera detta nummer med 24 , 24*60 respektive 24*60*60 .

Det föregående exemplet kan ändras för att få dagar, timmar, minuter och sekunder mellan två datum med hjälp av:

SELECT TRUNC( difference                       ) AS days,
       TRUNC( MOD( difference * 24,       24 ) ) AS hours,
       TRUNC( MOD( difference * 24*60,    60 ) ) AS minutes,
       TRUNC( MOD( difference * 24*60*60, 60 ) ) AS seconds
FROM   (
  SELECT TO_DATE( '2016-01-02 01:01:12', 'YYYY-MM-DD HH24:MI:SS' )
         - TO_DATE( '2016-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS' )
         AS difference
  FROM   DUAL

);

(Obs: TRUNC() används snarare än FLOOR() att hantera negativa skillnader korrekt.)

utgångar:

DAYS HOURS MINUTES SECONDS
---- ----- ------- -------
   1     1       1      12

Det föregående exemplet kan också lösas genom att konvertera den numeriska skillnaden till ett intervall med NUMTODSINTERVAL() :

SELECT EXTRACT( DAY    FROM difference ) AS days,
       EXTRACT( HOUR   FROM difference ) AS hours,
       EXTRACT( MINUTE FROM difference ) AS minutes,
       EXTRACT( SECOND FROM difference ) AS seconds
FROM   (
  SELECT NUMTODSINTERVAL(
           TO_DATE( '2016-01-02 01:01:12', 'YYYY-MM-DD HH24:MI:SS' )
             - TO_DATE( '2016-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS' ),
           'DAY'
         ) AS difference
  FROM   DUAL
);

Datum aritmetik - Skillnad mellan datum i månader eller år

Skillnaden i månader mellan två datum kan hittas med MONTHS_BETWEEN( date1, date2 ) :

SELECT MONTHS_BETWEEN( DATE '2016-03-10', DATE '2015-03-10' ) AS difference FROM DUAL;

utgångar:

DIFFERENCE
----------
        12

Om skillnaden inkluderar delmånader returnerar den bråkdelen av månaden baserat på att det finns 31 dagar i varje månad:

SELECT MONTHS_BETWEEN( DATE '2015-02-15', DATE '2015-01-01' ) AS difference FROM DUAL;

utgångar:

DIFFERENCE
----------
 1.4516129

På grund av att MONTHS_BETWEEN antar 31 dagar per månad när det kan vara färre dagar per månad kan detta resultera i olika värden för skillnader som sträcker sig över gränserna mellan månader.

Exempel:

SELECT MONTHS_BETWEEN( DATE'2016-02-01', DATE'2016-02-01' - INTERVAL '1' DAY ) AS "JAN-FEB",
       MONTHS_BETWEEN( DATE'2016-03-01', DATE'2016-03-01' - INTERVAL '1' DAY ) AS "FEB-MAR",
       MONTHS_BETWEEN( DATE'2016-04-01', DATE'2016-04-01' - INTERVAL '1' DAY ) AS "MAR-APR",
       MONTHS_BETWEEN( DATE'2016-05-01', DATE'2016-05-01' - INTERVAL '1' DAY ) AS "APR-MAY"
FROM   DUAL;

Produktion:

JAN-FEB FEB-MAR MAR-APR APR-MAY
------- ------- ------- -------
0.03226 0.09677 0.03226 0.06452

Skillnaden i år kan hittas genom att månadsskillnaden delas med 12.

Extrahera år, månad, dag, timme, minut eller andra delar av ett datum

Året, månaden eller DATE av en DATE datatyp kan hittas med hjälp av EXTRACT( [ YEAR | MONTH | DAY ] FROM datevalue )

SELECT EXTRACT (YEAR  FROM DATE '2016-07-25') AS YEAR,
       EXTRACT (MONTH FROM DATE '2016-07-25') AS MONTH,
       EXTRACT (DAY   FROM DATE '2016-07-25') AS DAY
FROM DUAL;

utgångar:

YEAR MONTH DAY
---- ----- ---
2016     7  25

Tiden (timme, minut eller sekund) komponenter kan hittas av antingen:

Till exempel:

SELECT EXTRACT( HOUR   FROM CAST( datetime AS TIMESTAMP ) ) AS Hours,
       EXTRACT( MINUTE FROM CAST( datetime AS TIMESTAMP ) ) AS Minutes,
       EXTRACT( SECOND FROM CAST( datetime AS TIMESTAMP ) ) AS Seconds
FROM   (
  SELECT TO_DATE( '2016-01-01 09:42:01', 'YYYY-MM-DD HH24:MI:SS' ) AS datetime FROM DUAL
);

utgångar:

HOURS MINUTES SECONDS
----- ------- -------
    9      42       1

Tidzoner och sommartid

DATE hanterar inte tidszoner eller förändringar i sommartid.

Antingen:

En DATE kan lagras som samordnad universaltid (UTC) och konverteras till den aktuella sessionstidszonen så här:

SELECT FROM_TZ(
         CAST(
           TO_DATE( '2016-01-01 12:00:00', 'YYYY-MM-DD HH24:MI:SS' )
           AS TIMESTAMP
         ),
         'UTC'
       )
       AT LOCAL AS time
FROM   DUAL;

Om du kör ALTER SESSION SET TIME_ZONE = '+01:00'; då är utgången:

TIME
------------------------------------
2016-01-01 13:00:00.000000000 +01:00

och ALTER SESSION SET TIME_ZONE = 'PST'; då är utgången:

TIME
------------------------------------
2016-01-01 04:00:00.000000000 PST

Hoppa sekunder

Oracle hanterar inte språngsekunder . Se My Oracle Support-not 2019397.2 och 730795.1 för mer information.

Få veckans dag

Du kan använda TO_CHAR( date_value, 'D' ) att få veckodag.

Detta är dock beroende av NLS_TERRITORY sessionsparametern:

ALTER SESSION SET NLS_TERRITORY = 'AMERICA';        -- First day of week is Sunday
SELECT TO_CHAR( DATE '1970-01-01', 'D' ) FROM DUAL;

Utgångar 5

ALTER SESSION SET NLS_TERRITORY = 'UNITED KINGDOM'; -- First day of week is Monday
SELECT TO_CHAR( DATE '1970-01-01', 'D' ) FROM DUAL;

Utgångar 4

För att göra detta oberoende av NLS inställningarna kan du stänga in datumet till midnatt på den aktuella dagen (för att ta bort eventuella fraktioner av dagar) och subtrahera det datum som trunkeras till början av den aktuella iso-veckan (som alltid börjar på måndag):

SELECT TRUNC( date_value ) - TRUNC( date_value, 'IW' ) + 1 FROM DUAL


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow