Para melhor visualização, recomendo resolução de no mínimo 1280 x 800 e navegador Mozilla Firefox


segunda-feira, 17 de agosto de 2009

Introdução ao tipo de dado TIMESTAMP e suas variações ...

Por Eduardo Legatti

Olá,

Sabemos que o tipo de dado DATE do Oracle é um tipo especial capaz de armazenar datas que vão de 4712 a.C. a 9999 d.C, mas além de armazenar informações de século, ano, mês e dia, o mesmo também é capaz de armazenar informações de hora, minuto e segundo. Mas aí você poderia perguntar: Se o tipo de dado DATE é capaz de manter essas informações temporais, isso não poderia ser considerado um TIMESTAMP? Não necessariamente. O tipo de dados TIMESTAMP introduzido à partir do Oracle 9i, vai muito mais além do que simplesmente armazenar de forma "crua" informações de data e horários. Podemos dizer que o tipo de dado TIMESTAMP é uma extensão do tipo de dados DATE, capaz de manter informações de tempo com maior precisão. No mais, neste artigo farei uma breve introdução a este tipo de dado e suas variações (WITH TIME ZONE e WITH LOCAL TIME ZONE) que, muitas vezes, é fonte de dúvida entre desenvolvedores e administradores de banco de dados quanto à sua aplicação e uso.

Antes de começar a descrever sobre o tipo de dados TIMESTAMP, irei iniciar através do exemplo abaixo, como poderíamos verificar informações de século, data e horários atuais, selecionando-as direto do banco de dados através do uso da função SYSDATE:

SQL> select to_char(to_date(0,'J'), 'dd/mm/yyyy ad') from dual;
select to_char(to_date(0,'J'), 'dd/mm/yyyy ad') from dual
*
ERRO na linha 1:
ORA-01854: data juliana deve estar entre 1 e 5373484

SQL> select
2 to_char(to_date(1,'J'), 'dd/mm/yyyy ad') de,
3 to_char(to_date(5373484,'J'), 'dd/mm/yyyy ad') ate
4 from dual;

DE ATE
--------------- ---------------
01/01/4712 a.C. 31/12/9999 d.C.

SQL> select to_char(sysdate,'cc dd/mm/yyyy hh24:mi:ss') data from dual;

DATA
----------------------
21 17/08/2009 08:10:25

Talvez você também já tenha ouvido falar da função CURRENT_DATE. A diferença entre ela e o SYSDATE é que a função SYSDATE retorna a data e horário do servidor, enquanto que a função CURRENT_DATE retorna a data e horário de acordo com o fuso horário da sessão do usuário. Para comprovar tal explicação, no exemplo abaixo irei alterar o fuso horário da minha sessão para o fuso horário de Nova York nos EUA que é '-5:00'. No servidor Oracle, o fuso horário está definido em '-3:00', ou seja, três horas de atraso em relação à hora de Greenwich.

SQL> alter session set nls_date_format='dd/mm/yyyy hh24:mi:ss';

Sessão alterada.

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
----------------
-03:00

SQL> alter session set time_zone='-5:00';

Sessão alterada.

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
----------------
-05:00

SQL> select sysdate,current_date from dual;

SYSDATE CURRENT_DATE
------------------- -------------------
17/08/2009 08:15:45 17/08/2009 06:15:45

Podemos perceber acima que SYSDATE retornou o horário do servidor, e CURRENT_DATE o horário de acordo com o fuso horário definido na minha sessão.

Bom, voltando ao assunto que originou este artigo e, como já dito anteriormente, o tipo de dados TIMESTAMP introduzido à partir do Oracle 9i é uma extensão do tipo de dados DATE. Além de armazenar o ano, mês, dia, horas, minutos e segundos do tipo de dados DATE, o mesmo é capaz também de armazenar o valor das frações de segundo. A precisão dessas frações, como o próprio nome já diz, nada mais é do que o número de dígitos da parte fracionária dos "segundos". Esta precisão pode ser um número de 0 a 9, mas quando não especificado, o seu valor padrão é 6.

SQL> create table t1 (ts_data timestamp);

Tabela criada.

SQL> desc t1
Nome Nulo? Tipo
---------------------------- -------- ------------------------
TS_DATA TIMESTAMP(6)


SQL> insert into t1 values (localtimestamp);

1 linha criada.

SQL> alter session set nls_timestamp_format = 'dd/mm/yyyy hh24:mi:ss.ff';

Sessão alterada.

SQL> select * from t1;

TS_DATA
--------------------------
05/08/2009 08:20:32.627869

Além do exemplo demonstrado acima, existem ainda duas variações do tipo de dados TIMESTAMP:


O tipo TIMESTAMP WITH TIME ZONE é uma variante de TIMESTAMP que inclui um deslocamento de fuso horário (TIME ZONE) em seu valor. Podemos dizer que o deslocamento de fuso horário em questão é a diferença em horas e minutos entre o horário local e o UTC. UTC é um acrônimo do Inglês para "Coordinated Universal Time" ou "Tempo Universal Coordenado" que corresponde ao fuso horário de referência a partir do qual se calculam todas as outras zonas horárias do mundo. Segundo algumas bibliografias, o UTC é o sucessor do Tempo Médio de Greenwich (Greenwich Mean Time), abreviadamente mais conhecido como GMT. Esta nova denominação foi cunhada para basear a medida do tempo nos padrões atômicos, mais do que nos celestes. Em resumo, dois valores TIMESTAMP WITH TIME ZONE serão considerados idênticos se representarem o mesmo instante em UTC, independente dos deslocamentos de fusos horários (TIME ZONE) armazenados nos dados. Confuso? Bom, para que não haja dúvidas, poderemos ver abaixo um exemplo que demonstra uma informação de data e horário que deverá ser reunida ou coordenada entre diferentes regiões geográficas com fusos horários distintos:

Por exemplo:

TIMESTAMP '17/08/2009 08:00:00 -3:00'

é o mesmo que

TIMESTAMP '17/08/2009 06:00:00 -5:00'

Isto é, 08:00 horas da manhã no horário de Brasília é o mesmo que 06:00 horas da manhã no horário de Nova York nos EUA.


O outro tipo, TIMESTAMP WITH LOCAL TIME ZONE é outra variante de TIMESTAMP que inclui um deslocamento de fuso horário em seu valor. A diferença é que este deslocamento não é armazenado como parte dos dados da coluna, mas sim, normalizado para o fuso horário do banco de dados (DBTIMEZONE). O verbo "normalizar", neste caso, eu entendo como um cálculo que é realizado tendo como base o fuso horário definido no banco de dados afim de se mostrar o horário local do usuário. Portanto, o Oracle retornará a informação de data, hora, minuto e segundo no fuso horário local da sessão que está acessando o dado. Vale a pena salientar que o uso desta variante é apropriado para aplicações onde se deseja exibir as datas e os horários usando o fuso horário do sistema cliente. Para quem já acessou algum tipo fórum ou lista de discussão de nível global, notará que ao postar algum tópico no fórum, a data e horário mostrada será convertida para o fuso horário local. Caso um leitor que esteja no Japão acessar o tópico, verá a data e horário de acordo com o fuso horário do Japão. Então, utilizando como base o exemplo anterior:

Supondo que eu esteja no Brasil (fuso horário -3:00) e insira a data e horário abaixo:

TIMESTAMP '17/08/2009 08:00:00'

e um usuário que esteja em Nova York (fuso horário -5:00) acessar o mesmo dado, a data apresentada para este usuário será

TIMESTAMP '17/08/2009 06:00:00'

No mais, para demonstrar o uso do tipo TIMESTAMP e suas duas variações, irei realizar algumas operações abaixo. Vale a pena salientar que o Oracle possui além das funções SYSDATE e CURENT_DATE, outras funções embutidas para capturar informações de data e horários atuais como, LOCALTIMESTAMP, CURRENT_TIMESTAMP e SYSTIMESTAMP onde:
  • LOCALTIMESTAMP: retorna um valor do tipo TIMESTAMP como data e horário corrente (incluindo frações de segundos), de acordo com o fuso horário definido na sessão do usuário.
  • CURRENT_TIMESTAMP: retorna um valor do tipo TIMESTAMP WITH TIME ZONE como data e horário corrente (incluindo frações de segundos), de acordo com o fuso horário definido na sessão do usuário.
  • SYSTIMESTAMP: retorna um valor do tipo TIMESTAMP WITH TIME ZONE como data e horário corrente (incluindo frações de segundos), de acordo com o fuso horário definido no sistema onde o servidor de banco de dados reside.
Para demonstrar o resultado das funções acima, executarei os comandos SQL abaixo:

SQL> alter session set time_zone='-5:00';

Sessão alterada.

SQL> select localtimestamp,current_timestamp,systimestamp from dual;

LOCALTIMESTAMP CURRENT_TIMESTAMP SYSTIMESTAMP
------------------------ ------------------------------- -------------------------------
17/08/09 06:20:54,656000 17/08/09 06:20:54,656000 -05:00 17/08/09 08:20:54,656000 -03:00

Podemos perceber pelo resultado acima que LOCALTIMESTAMP e CURRENT_TIMESTAMP apresentaram o mesmo horário, a diferença é que CURRENT_TIMESTAMP trouxe a informação do fuso horário (-5:00). Já a função SYSTIMESTAMP, diferente de CURRENT_TIMESTAMP, trouxe o horário de acordo com o fuso horário definido no sistema do servidor de banco de dados.

Irei agora criar uma tabela de teste conforme abaixo:

SQL> create table t2 (
2 a timestamp,
3 b timestamp with time zone,
4 c timestamp with local time zone
5 );

Tabela criada.

SQL> desc t2
Nome Nulo? Tipo
------------------------- -------- ---------------------------------
A TIMESTAMP(6)
B TIMESTAMP(6) WITH TIME ZONE
C TIMESTAMP(6) WITH LOCAL TIME ZONE

SQL> insert into t2 values (localtimestamp,localtimestamp,localtimestamp);

1 linha criada.

SQL> select * from t2;

A B C
------------------------ ------------------------------- ------------------------
17/08/09 08:30:10,250000 17/08/09 08:30:10,250000 -03:00 17/08/09 08:30:10,250000

Independente da função utilizada, as informações de data e horários foram inseridas nas devidas colunas e mostram o mesmo horário. Agora irei realizar através de uma aplicação (no meu caso o SQL*Plus), a simulação do acesso remoto ao banco de dados na qual o usuário está localizado em uma região geográfica onde fuso horário desta região seja diferente como, por exemplo, Nova York nos EUA:

SQL> alter session set time_zone='-5:00';

Sessão alterada.

SQL> select dbtimezone,sessiontimezone from dual;

DBTIMEZONE SESSIONTIMEZONE
---------- ---------------
-03:00 -05:00

SQL> select * from t2;

A B C
------------------------ ------------------------------- ------------------------
17/08/09 08:30:10,250000 17/08/09 08:30:10,250000 -03:00 17/08/09 06:30:10,250000

De acordo com o resultado acima, podemos notar que os resultados das colunas A e B não se alteraram, ou seja, como o usuário Nova Yorkino não tem conhecimento do fuso horário da região de onde está localizado o banco de dados, o valor da coluna A seria um tanto impreciso. Já o valor da coluna B faria mais sentido pelo fato de apresentar a informação do fuso horário, ou seja, o usuário saberia de forma precisa, o horário em que o dado foi gravado. Por último, podemos perceber que o valor da coluna C foi automaticamente "convertido" para o fuso horário da sessão do usuário que, neste caso é '-5:00'.

Concluindo, o tipo de dado TIMESTAMP WITH LOCAL TIME ZONE é ideal e apropriado para aplicações onde se deseja exibir informações de data e horários usando o fuso horário do sistema cliente.



20 comentários:

Unknown disse...

Fala Eduardo,

É impressionante o nível dos seus posts.Está de parabéns .
Neles podemos ver a dedicação com que você escreve os seus posts.

Muito bom!

Abs,

JC

Anônimo disse...

Eduardo muito bom este artigo.

eu gostaria de saber como que eu faço para alterar a data do meu banco de dados, eu nao queria alterar a minha sessao.

aqui no meu banco por exemplo esta aparecendo desta forma:

select sysdate,current_date,localtimestamp,current_timestamp,systimestamp from dual;

SYSDATE CURRENT_DATE LOCALTIMESTAMP CURRENT_TIMESTAMP SYSTIMESTAMP
1 8/30/2009 2:28:11 PM 8/30/2009 2:28:12 PM 30/08/09 14:28:11,966000 30/08/09 14:28:11,966000 -03:00 30/08/09 14:28:11,966000 -03:00

Anônimo disse...

eu queria somente alterar as datas SYSDATE e CURRENT_DATE, que estao no farmato americano.

queria que ficassem dd-mm-yyyy.

Eduardo Legatti disse...

Olá Marlon,

O valor da data (por exemplo, retornadas pelas funções SYSDATE e CURRENT_DATE) são dependentes da data definida no sistema operacional onde o Oracle reside. No caso da formatação, essas configurações normalmente derivam da variável de ambiente do Oracle NLS_LANG:

NLS_LANG=language_territory.charset

e a configuração da mesma na máquina cliente, seja via chave NLS_DATE_FORMAT criada no regedit, ou uma variável de ambiente do Windows/Linux, etc.., sempre irá sobrescrever a formatação padrão. Você poderá checar a configuração NLS atual da instância Oracle através da view NLS_INSTANCE_PARAMETERS. Há também outras views que não vêm ao caso como NLS_DATABASE_PARAMATERS e DATABASE_PROPERTIES.

SQL> select value from nls_instance_parameters where parameter='NLS_DATE_FORMAT';

VALUE
----------------------------------------
DD-MM-RR

SQL> select sysdate,current_date from dual;

SYSDATE CURRENT_
-------- --------
30/08/09 30/08/09

Você poderia utilizar a função TO_CHAR ...

SQL> select to_char(sysdate,'dd-mm-yyyy'),to_char(current_date,'dd-mm-yyyy') from dual;

TO_CHAR(SY TO_CHAR(CU
---------- ----------
30-08-2009 30-08-2009

ou alterar a sua sessão ...

SQL> alter session set nls_date_format='dd-mm-yyyy';

Sessão alterada.

SQL> select sysdate,current_date from dual;

SYSDATE CURRENT_DA
---------- ----------
30-08-2009 30-08-2009

Uma outra forma seria alterar o parâmetro de inicialização abaixo, na qual não tenho muita confiança ...

SQL> alter system set NLS_DATE_FORMAT='DD-MM-YYYY' scope=spfile;

Sistema alterado.

Após reinicializar a instância ...

NAME TYPE VALUE
------------------ ----------- --------------
nls_date_format string DD-MM-YYYY

De qualquer forma, independente da configuração setada no servidor, eu recomendaria à você criar uma variável de ambiente no sistema operacional local chamada de NLS_DATE_FORMAT com o valor 'DD-MM-YYYY'. No mais, acredito que o formato mais usual para nós brasileiros seria DD/MM/YYYY.

Para maiores informações acesse o link NLS_LANG FAQ que com certeza irá lhe ajudar.

Abraços e até mais ...

Unknown disse...

Obrigado pela Ajuda Eduardo, fiz os procedimentos conforme voce indicou mas mesmo assim eu nao consegui.

o meu sistema operacional é o Windows 7 e Oracle 11g, esta todo em portugues configurações regionais Portugues Brasil etc.

Primeiramente eu verifiquei conforme a instrução: select * from nls_instance_parameters
where parameter='NLS_DATE_FORMAT';

onde nao existia nenhuma informação, foi entao que eu fiz as alterações:

alter system set NLS_DATE_FORMAT='DD-MM-YYYY' scope=spfile;
alter system set NLS_TERRITORY ='BRAZIL' scope=spfile;

alterei tambem o territorio que estava AMERICA, pensei que era isso o problema.

Reiniciei o banco mas ainda continua buscando a data americana.

Existe um detalhe interessante na ferramenta do PL/SQL em Tools -> Preferences -> Date/Time, la existem tres opçoes de data:

a do windows que mostra que minha data esta americana, a do Oracle que esta BR e a Definida pelo usuario que tambem esta BR.

O problema é que, meu windows esta com todas as configurações de data BR, no registro do windows tambem esta definida correta:
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraDb11g_home1;

BRAZILIAN PORTUGUESE_BRAZIL.WE8MSWIN1252.

E tambem no regitro do windows existe as configuraçoes de data do usuario CURRENT que tambem esta tudo definido como BR:
HKEY_CURRENT_USER\Control Panel\International

Se eu colocar na ferramenta do PL/SQL como a data definida pelo Oracle,Blz quando executo o select o mesmo traz a data correta, o problema é que na minha aplicação da erro de data, por que deve pegar alguma configuraçao de outro local.

ai eu nao consigo prosseguir.

Unknown disse...

Obs. Na minha aplicação apos fazer a conexao eu tambem altero a sessao do usuario:
Conexao.ExecuteDirect('alter session set NLS_LANGUAGE = ' + QuotedStr('BRAZILIAN PORTUGUESE'));
Conexao.ExecuteDirect('alter session set NLS_TERRITORY = ' + QuotedStr('BRAZIL'));
Conexao.ExecuteDirect('alter session set NLS_CURRENCY = ' + QuotedStr('R$'));
Conexao.ExecuteDirect('alter session set NLS_ISO_CURRENCY = ' + QuotedStr('BRAZIL'));
Conexao.ExecuteDirect('alter session set NLS_NUMERIC_CHARACTERS = ' + QuotedStr('.,'));
Conexao.ExecuteDirect('alter session set NLS_CALENDAR = ' + QuotedStr('GREGORIAN'));
Conexao.ExecuteDirect('alter session set NLS_DATE_FORMAT = ' + QuotedStr('DD/MM/RRRR'));
Conexao.ExecuteDirect('alter session set NLS_DATE_LANGUAGE = ' + QuotedStr('BRAZILIAN PORTUGUESE'));
Conexao.ExecuteDirect('alter session set NLS_SORT = ' + QuotedStr('WEST_EUROPEAN'));
Conexao.ExecuteDirect('alter session set NLS_TIME_FORMAT = ' + QuotedStr('HH24:MI:SSXFF'));
Conexao.ExecuteDirect('alter session set NLS_TIMESTAMP_FORMAT = ' + QuotedStr('DD/MM/RRRR HH24:MI:SSXFF'));
Conexao.ExecuteDirect('alter session set NLS_TIME_TZ_FORMAT = ' + QuotedStr('HH24:MI:SSXFF TZR'));
Conexao.ExecuteDirect('alter session set NLS_TIMESTAMP_TZ_FORMAT = ' + QuotedStr('DD/MM/RRRR HH24:MI:SSXFF TZR'));
Conexao.ExecuteDirect('alter session set NLS_DUAL_CURRENCY = ' + QuotedStr('Cr$'));
Conexao.ExecuteDirect('alter session set NLS_COMP = ' + QuotedStr('BINARY'));
Conexao.ExecuteDirect('alter session set NLS_LENGTH_SEMANTICS = ' + QuotedStr('BYTE'));
Conexao.ExecuteDirect('alter session set NLS_NCHAR_CONV_EXCP = ' + QuotedStr('FALSE'));


Na empresa onde eu trabalho minha aplicação funciona perfeitamente la é Oracle 10g Windows XP.

mas muito obrigado pela ajuda, ja me ajudou bastante e obrigado pelo link NLS_LANG vou ver se consego buscar mais algumas informações.

Sucesso pra você Eduardo!!!

Eduardo Legatti disse...

Olá Marlon,

Windows 7? Ainda não tive a oportunidade de realizar quaisquer testes no Windows 7. Realmente o problema é saber de onde está vindo esta formatação. Você já tentou criar a variável de ambiente NLS_DATE_FORMAT no Windows? Digo, lá em meu computador -> avançado -> variáveis de ambiente. Em um primeiro instante, realize testes utilizando o SQL*PLUS antes que qualquer outra ferramenta. Já em relação aos comandos ALTER SESSION que são executados dentro da sua aplicação, eu realmente considero uma boa prática. Normalmente eu altero somente NLS_LANGUAGE, NLS_TERRITORY e NLS_DATE_FORMAT de forma a sobrescrever qualquer configuração local do cliente durante a execução da aplicação.

C:\>SET NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252

C:\>SET NLS_DATE_FORMAT=MM-DD-RR

C:\>sqlplus scott/tiger

SQL*Plus: Release 11.1.0.6.0 - Production on Mon Aug 31 09:00:55 2009

Copyright (c) 1982, 2007, Oracle. All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> select sysdate from dual;

SYSDATE
--------
08-31-09

SQL> select * from nls_session_parameters;

PARAMETER VALUE
------------------------------ ----------------------------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT MM-DD-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY $
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE

17 rows selected.

SQL> ALTER SESSION SET NLS_LANGUAGE = 'BRAZILIAN PORTUGUESE';

Sessão alterada.

SQL> ALTER SESSION SET NLS_TERRITORY = 'BRAZIL';

Sessão alterada.

SQL> ALTER SESSION SET NLS_DATE_FORMAT= 'DD/MM/YYYY';

Sessão alterada.

SQL> select * from nls_session_parameters;

PARAMETER VALUE
------------------------------ --------------------------
NLS_LANGUAGE BRAZILIAN PORTUGUESE
NLS_TERRITORY BRAZIL
NLS_CURRENCY R$
NLS_ISO_CURRENCY BRAZIL
NLS_NUMERIC_CHARACTERS ,.
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD/MM/YYYY
NLS_DATE_LANGUAGE BRAZILIAN PORTUGUESE
NLS_SORT WEST_EUROPEAN
NLS_TIME_FORMAT HH24:MI:SSXFF
NLS_TIMESTAMP_FORMAT DD/MM/RR HH24:MI:SSXFF
NLS_TIME_TZ_FORMAT HH24:MI:SSXFF TZR
NLS_TIMESTAMP_TZ_FORMAT DD/MM/RR HH24:MI:SSXFF TZR
NLS_DUAL_CURRENCY Cr$
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE

17 linhas selecionadas.

SQL> select sysdate from dual;

SYSDATE
----------
31/08/2009

Abraços e até mais ...

Anônimo disse...

Boa tarde Eduardo,

acredito que seja algum "BUG DO WINDOWS 7", por que quando eu formatei minha maquina o idioma e formatação padrão do windows era Americano.

Para colocar o idioma Português eu Baixei os pacotes de Idiomas no windows Update, (o windows 7 baixa as atualizações de idioma e instala tudo automáticamente, depois é só reiniciar ir em configurações regionais e definir todas as configurações BR).

Acredito que nesta hora o windows não altere todas as configurações
Alterando somente algumas configurações básicas..


Eduardo no seu blog nao teria como eu colocar imagens, ficaria melhor para voce verificar como que esta.

Anônimo disse...

Em relação as variáveis Local da minha maquina eu inseri aqui, não alterou nada no windows 7.

Eduardo Legatti disse...

Olá Marlon,

O blogger não permite imagens nos comentários. Já em relação ao Windows 7, ainda a Oracle não se manifestou sobre suporte ao mesmo. Aliás, acho que aqui no Brasil o mesmo começará a ser vendido em meados de Outubro. Portanto, acredito que você ainda irá queimar alguns neurônios ;-)

Abraços e até mais ...

Eduardo Legatti disse...

Olá Marlon,

Concluindo, se o teste abaixo não funcionar no Prompt do DOS, então realmente existe algum problema na instalação ...

C:\>sqlplus legatti/manager

SQL*Plus: Release 11.1.0.6.0 - Production on Seg Ago 31 16:53:43 2009

Copyright (c) 1982, 2007, Oracle. All rights reserved.

Conectado a:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> select sysdate from dual;

SYSDATE
----------
31/08/2009

SQL> exit
Desconectado de Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

C:\>set nls_date_format=DD-MM-YYYY

C:\>sqlplus legatti/manager

SQL*Plus: Release 11.1.0.6.0 - Production on Seg Ago 31 16:54:21 2009

Copyright (c) 1982, 2007, Oracle. All rights reserved.

Conectado a:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> select sysdate from dual;

SYSDATE
----------
31-08-2009

Abraços e até mais ...

Unknown disse...

Por fim, chamei o DBA Oracle da empresa onde eu trabalho, o mesmo ficou quase 2 horas para tentar corrigir o problema, Mas sem sucesso.

Fez as configurações de Data de todas as formas, tanto Oracle como no windows.

o mesmo reportou nunca ter visto uma situação igual a esta, segundo ele as configurações que ele fez teria que funcionar.

Minha conclusão é que o Windows 7 possui em algum lugar do sistema outra configuração de data, por que as padrões não funcionam para este caso especifico.

pode ser que, como ele é ainda uma versão de "testes" a microsoft não liberou algumas configurações de data para não comprometer o sistema, sabendo que ele terá um prazo de validade para utilização ate 1 junho de 2010.

isso é o que eu acho, ja nao tenho a menor idéia do que pode ser.

abrcss... a vou formatar minha maquina chega de quebrar a cabeça....

Unknown disse...

Boa Noite Eduardo,

identificado o problema, o mesmo esta na data da BIOS da minha placa mae.

ela esta com formato americano, onde agora eu tenho um novo problema, nao consigo alterar para o formato brasileiro.

abrcss at++

Eduardo Legatti disse...

Olá Marlon,

Muito estranho. Não imaginava que o formato da data na BIOS impactaria no formato da data do sistema operacional. Afinal, é somente uma máscara ;-)

Boa sorte e até mais ...

Anônimo disse...

Ola Eduardo,

eu tambem fiquei em duvida sobre isso, mas consegui resolver meu problema.

atualizei a Bios American Megatrends que estava na versao V1.0B25 agora esta V1.0B27.

Formatei novamente com o Windows 7 onde o mesmo ja identificou a data correta.

a primeira coisa que eu fiz foi instalar o PL/SQL e ir em propriade de datas e verificar como que estava o formato da data no windows, onde estava correto.

abrcsss..

Eduardo Legatti disse...

Olá Marlon,

Em resumo, valeu o empenho e a persistência ;-)

Abraços e até mais ...

Alessandro Cordeiro disse...

Olá Eduardo, só tenho uma duvida, como dentro do Oracle eu sei que o meu cliente esta no EUA ou no Brasil? Pois primeiro preciso saber disse para depois fazer o ALTER SESSION.

Obrigado!

Eduardo Legatti disse...

Olá Alessandro,

Não sei se entendi bem a sua dúvida, mas pelo que sei, não tem como saber o timezone de sessões atualmente conectadas no banco, a não ser a sua própria sessão através da instrução "SELECT SESSIONTIMEZONE FROM DUAL". Caso você precise, por algum motivo, pegar essa informação das sessões conectadas através da view V$SESSION, então a cada conexão realizada por um usuário, você poderia armazenar essa informação. Para maiores informações, acesse o link do artigo abaixo:

http://eduardolegatti.blogspot.com/2009/05/um-pouco-do-pacote-dbmsapplicationinfo.html

Abraços e até mais ...

dfigueira disse...

Olá Eduardo, obrigado por compartilhar seu conhecimento.
Tenho uma situação em que a data vem no seguinte formato 2020-01-01T05:00:20-03:00,
Não encontrei ainda nenhuma forma de converter este valor para o formato brasileiro, você poderia dar alguma dica sobre isso.

Muito Obrigado.

Eduardo Legatti disse...

Olá Daniel,

Me parece que é um formato TIMESTAMP WITH TIMEZONE. Para converter, acredito que você terá que tirar a diferença do time zone que está vindo (nesse caso -03:00) e fazer a conversão conforme exemplo a seguir.

SELECT TO_CHAR(CAST(TO_TIMESTAMP_TZ('2020-01-01T05:00:20-03:00', 'yyyy-mm-dd"T"hh24:mi:ss TZH:TZM') AT TIME ZONE '+3:00' AS DATE),'dd/mm/yyyy hh24:mi:ss') DATA FROM DUAL

DATA
-------------------
01/01/2020 05:00:20

Abraços,

Legatti

Postagens populares