2010-11-30 30 views
0

J'ai un magasin de dates dans la base de données comme valeur longue dans varchar par exemple: 1230748200000. J'ai besoin de sortir l'année avec la requête oracle .. comment puis-je le faire en oracle? Y at-il un moyen que je peux cacher cela dans une date afin que je puisse obtenir l'année? Le problème est que je ne peux pas utiliser to_char (SYSTIMESTAMP, 'aaaa') ou to_Date parce que je n'ai pas la date au format Timestamp ou Date ... au lieu de l'avoir aussi longtemps varcharDate d'obtention d'une valeur longue var var millisecondes stockée dans Oracle Database

Merci.

Editer: Pouvez-vous s'il vous plaît donner une solution pour le scénario suivant. Je 1262284398000 dans ma table Enregistrer sous var char.so comme je l'ai dit que je dois obtenir l'année j'utilise l'instruction SQL suivante qui reviennent année 2009

select 
to_char(
to_date('01-JAN-1970','DD-MM-YYYY HH24:MI SS') + (1262284398000/(1000*60 * 60 * 24)) ,'YYYY') 
from dual ; 

Mais dans les déclarations même valeur de code java date que 2010 pour l'année est d'obtenir diferent,

Calendar c = Calendar.getInstance(); 
    c.setTimeInMillis(1262284398000l); 
    System.out.println(c.getTime()); 
    System.out.println(c.get(Calendar.YEAR)); 

qui date de retour comme ven 1 janvier 00:03:18 IST2010 Pourquoi la différence ici s'il vous plaît?

+0

concernant la différence entre les résultats Java et Oracle: je ne sais pas, et je n'ai pas Java installé pour pouvoir jouer avec. Est-ce que Java signale que le 29 février 2000 est une date invalide? Juste curieux. –

Répondre

2

Jetez un oeil here pour plus d'informations

select epoch_time, extract(year from epoch_time) as year 
from (
    select date '1970-01-01' + 1291116794/86400 as epoch_time 
    from dual 
) 

Il peut y avoir des problèmes autour de fuseaux horaires, etc. puisque je crois que le temps d'époque sera en UTC mais qui est au-delà de ma ken.

En outre, il semble que votre valeur est de 13 chiffres plutôt que 10, alors peut-être vous juste besoin d'ajouter quelques zéros supplémentaires, à savoir diviser par 86.400.000 plutôt que 86400.

EDIT: Comme je l'ai dit ci-dessus .. .. il peut y avoir des problèmes de fuseau horaire. Il semble que le code Java prend 1970-01-01 (en UTC, comme il se doit) en ajoutant le décalage et en le convertissant en heure locale. Vous devrez également le faire avec la requête de base de données.

Je suis pas très clair sur la façon dont les fuseaux horaires gère Oracle, mais après un peu d'expérimenter je suis venu avec les exemples suivants

alter session set time_zone = 'Asia/Calcutta'; 
select 
    sessiontimezone, 
    to_char(to_date('01-JAN-1970','DD-MM-YYYY HH24:MI SS') + 
    (1262284398000/(1000*60 * 60 * 24)) ,'YYYY'), 
    extract(year from cast(timestamp '1970-01-01 00:00:00 +00:00' at local + 
    numtodsinterval(1262284398000/1000, ' SECOND') as timestamp with time zone)), 
    to_char(timestamp '1970-01-01 00:00:00 +00:00' at local + 
    numtodsinterval(1262284398000/1000, ' SECOND'), 'YYYY'), 
    extract(year from cast(timestamp '1970-01-01 00:00:00 +00:00' at local + 
    numtodsinterval(1262284398000/1000, ' SECOND') as timestamp with local time 
    zone)) 
from dual; 

Dans l'exemple ci-dessus, les deux premières colonnes (après SessionTimeZone) devrait être 2009 et les deux derniers devraient être 2010. Bien que tout cela vient d'être trouvé par l'expérimentation, votre kilométrage peut varier.

1

@MikeyByCrikey a affiché un bon point de départ, mais il y a deux ou trois questions auxquelles vous devez répondre avant de pouvoir convertir votre valeur de chaîne à une date:

A. Quelle est la date représentée par « 0 »? Autrement dit, d'où part cette valeur de comptage en millisecondes? Dans l'exemple de @ Mikey, la date Unix 'begin' (aussi appelée 'date de l'époque') du 01-Jan-1970 est utilisée, mais il n'y a pas assez d'informations dans votre message pour savoir ce qu'est réellement la date '0'. D'autres systèmes utilisent différentes dates d'époque. Par exemple, sur les systèmes exécutant le système d'exploitation VMS, la date d'époque est le 17 novembre 1858 (se trouve être le jour julien 2 400 000); Windows (versions 32 et 64 bits) utilise 01-Jan-1601 (première année du cycle du calendrier grégorien de 400 ans qui était en cours lorsque cet OS a été conçu); et d'autres systèmes informatiques utilisent des dates «0» différentes. B. Conversion d'une chaîne en nombre dans Oracle est assez facile.Je venais d'utiliser la fonction TO_NUMBER, comme dans:

strMillisecs VARCHAR2(100) := '1230748200000'; 
    nMilliseconds NUMBER; 

    nMilliseconds := TO_NUMBER(strMillisecs); 

C. Une fois que vous avez obtenu à ce point (la date « 0 » est connu, et la chaîne est convertie en nombre) l'année peut être extrait comme suit:

dtEpoch_date   DATE := TO_DATE('01-JAN-1970', 'DD-MON-YYYY'); -- for example 
    strMillisecs   VARCHAR2(100) := '1230748200000'; 
    nMilliseconds  NUMBER; 
    dtTarget_date  DATE; 
    nYear    NUMBER; 
    nMillisecs_in_a_day NUMBER := 86400000; 

    nMilliseconds := TO_NUMBER(strMillisecs); 

    -- Note: there are 

    dtTarget_date := dtEpoch_date + (nMilliseconds/nMillisecs_in_a_day); 

    -- FINALLY! 

    nYear := TO_NUMBER(TO_CHAR(dtTarget_date, 'YYYY')); 

Espérons que cela soit utile.

Partagez et appréciez.

+0

Merci Bob pour la réponse.pouvez-vous s'il vous plaît jeter un oeil à l'édition sur la question où je décris le dernier numéro que je viens – Harshana

1

Nous voulions convertir des valeurs longues stockées dans la base de données en valeurs TIMESTAMP dans le fuseau horaire central.

Cela a fonctionné.

select FROM_TZ(
    TO_TIMESTAMP('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + 
    NUMTODSINTERVAL(1386655200000/1000,'SECOND'), 
    'UTC') at time zone 'America/Chicago' 
from dual 

Lorsque 1386655200000 est la valeur d'une milliseconde d'un java.util.Date le 10 décembre 2013, fuseau horaire central.