| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/02/2005 18:29:31
|
renatosilva
GUJ Master
Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline
|
Alguém já precisou converter data de Delphi para Java?
Bem se não me engano o formato interno das datas em Java é um long de milissegundos desde não sei quando. Já no delphi é um ponto flutuante (double) com a seguinte faixa:
Valor mínimo: -657434.0 (01/01/0100 12:00:00.000 AM)
Valor máximo: 2958465.99999 (31/12/9999 11:59:59.999 PM)
Eu preciso disso porque o banco que acesso com Java é lido e escrito por um alienígena escrito em Delphi.
Já verifiquei e essa faixa cabe no campo do banco de dados, apesar de uma parada sinistra aí. Aliás no MySQL tem uma coisa muito louca: ÀS VEZES ele PERMITE chaves primárias IGUAIS e ÀS VEZES NÃO, sem nenhuma explicação aparente!!! Esse campo de data que é um float no formato do Delphi é que é a chave primária.
De qualquer forma continuarei pesquisando...
This message was edited 1 time. Last update was at 24/02/2005 18:29:54
|
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/02/2005 18:51:30
|
thingol
Moderador
Membro desde: 29/07/2004 16:10:13
Mensagens: 17539
Offline
|
Quanto o Delphi retorna para a data 1/1/1970 (que para o Java é o tempo 0?) Aí dá para fazer umas contas.
|
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/02/2005 19:16:27
|
renatosilva
GUJ Master
Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline
|
thingol wrote:Quanto o Delphi retorna para a data 1/1/1970 (que para o Java é o tempo 0?) Aí dá para fazer umas contas.
´
É disso que estou com medo, de fazer as contas!!!
Queria achar algo pronto.
Bem vou ver isso aí e posto depois...
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 24/02/2005 21:52:37
|
fzampa
Virtual Machine Man
![[Avatar]](/images/avatar/e2c4a40d50b47094f571e40efead3900.jpg)
Membro desde: 05/11/2004 18:22:45
Mensagens: 615
Localização: Belo Horizonte
Offline
|
Se tivesse guardado no formato Date do banco de dados teria dado esse problema??? Como está guardada a data?
This message was edited 1 time. Last update was at 25/02/2005 00:01:38
|
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 25/02/2005 13:27:40
|
renatosilva
GUJ Master
Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline
|
@editado
fzampa wrote:Se tivesse guardado no formato Date do banco de dados teria dado esse problema??? Como está guardada a data?
Aí é que tá, o programa em Delphi armazena a data como um campo float e não como um date que provavelmente o MySQL tem. E não posso mudar esse fato.
Caras por enquanto estou dando uma pesquisada numas coisas, depois posto mais... agora vou almoçar
This message was edited 1 time. Last update was at 25/02/2005 13:31:01
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 25/02/2005 13:44:59
|
Daniel Quirino Oliveira
Moderador
![[Avatar]](/images/avatar/846c260d715e5b854ffad5f70a516c88.png)
Membro desde: 23/03/2003 23:57:34
Mensagens: 3282
Localização: Awawawawa (Araraquara) - SP
Offline
|
Diquinha quente: http://joda-time.sourceforge.net/
This message was edited 1 time. Last update was at 25/02/2005 13:45:08
|
Daniel Quirino Oliveira |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 25/02/2005 15:31:11
|
renatosilva
GUJ Master
Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline
|
Nome esquisito: Joda, mistura de Java com...
O difícil é achar informações, mas estou olhando a documentação...
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 25/02/2005 19:06:56
|
renatosilva
GUJ Master
Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline
|
Minhas conclusões até agora:
Bem a data e a hora do Delphi ficam num TDateTime, que é um apelido para o tipo Double (8 bytes). Ele armazena o número de dias passados desde 30/12/1899, indo para valores negativos e positivos, observando-se os valores limites já citados. E também pode admitir valores fracionários, de modo que a data 30/12/1899 12h:0min:0s:0ms é representada como 0,5. A parte fracionária então representa as horas, minutos, segundos e milissegundos, ocupando para isso uma faixa de 8 dígitos na base 10, de modo que a data 30/12/1899 23h:59min:59s:999ms é representada por 0,99999999).
Parêntesis: por isso a data máxima limite indicada acima como 31/12/9999 11:59:59.999 na verdade é representada pelo valor 2958465.99999999 e não 2958465.999999, que na verdade representa a data 31/12/9999 11:59:59.136 (136 milissegundos e não 999).
Bem descobri essas coisas olhando o código das funções EncodeDate e EncodeTime, que pegam valores separados de ano/mês/dia e hora/minuto/segundo/milissegundo, respectivamente, e transformam num TDateTime cada uma, bastando somar os dois valores para obter a representação conjunta de data e hora.
Tal representação é como a do Java, só que este usa um inteiro (long) de se não me engano 8 bytes também, que representa os milisegundos desde 1/1/1970 (isso tem a ver com Unix) enquanto que TDateTime representa dias desde 30/12/1899, e de modo fracionário, o que permite também reepresentar os milissegundos.
Bem se eu não achar algo pronto, vou ter que implementar essas funções EncodeDate e EncodeTime em Java, adaptando o algoritmo usado. E também terei que adaptar as funções contrárias, de decodificação, já que fazemos consultas no banco de dados pelo Java. Bem se tiver que fazer isso provavelmente vou usar o GregorianCalendar ou então o Joda-time que o Quirino indicou. Aliás procurei e não achei nada na documentação dessa ferramenta sobre converter para esse formato do Delphi ou qualquer outro. Mas minha impressão é que ela é uma boa biblioteca para trabalhar. Bem, ela diz que a API de datas do Java é lenta e ineficiente.
PS: no meu micro o long zero é retornado pela classe java.util.Date como 31/12/1969 21h, ou seja três horas antes que o normal. Meu SO é Windows e o fuso horário é GMT -3h. Muito estranho isso, espero descobrir o que está acontecendo.
Bem vou continuar nessa labuta e continuo aceitando sugestões.
This message was edited 1 time. Last update was at 25/02/2005 19:12:36
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/02/2005 17:34:24
|
renatosilva
GUJ Master
Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline
|
Bem acho que com o que descobri agora já dá pra fazer o que eu quero!!
renato3110 wrote:Parêntesis: por isso a data máxima limite indicada acima como 31/12/9999 11:59:59.999 na verdade é representada pelo valor 2958465.99999999 e não 2958465.999999, que na verdade representa a data 31/12/9999 11:59:59.136 (136 milissegundos e não 999).
Na verdade 2958465.99999999 ainda é um valor aproximado, arredondado em milissegundos. Isto explica as frações abaixo ou acima do valor original na operação contrária. Tais frações devem ser arredondadas para corrigir a aproximação inicial.
renato3110 wrote:PS: no meu micro o long zero é retornado pela classe java.util.Date como 31/12/1969 21h, ou seja três horas antes que o normal. Meu SO é Windows e o fuso horário é GMT -3h. Muito estranho isso, espero descobrir o que está acontecendo.
Bem quanto à isso o que acontece é que ao formatar a data eu obtenho o valor para o meu fuso horário (-3h) automaticamente. A data 1/1/1970 0h é referente ao GMT 00:00. Na verdade não compreendo qual era a minha dúvida quanto à isso!!!
renato3110 wrote:Aliás no MySQL tem uma coisa muito louca: ÀS VEZES ele PERMITE chaves primárias IGUAIS e ÀS VEZES NÃO, sem nenhuma explicação aparente!!!
Bem anida queria saber isso!! Alguém tem uma luz????
Conversão de datas
Bem, o principal formato de data no Delphi é o utilizado pelo TDateTime, relacionado à "automação OLE" e com as seguntes características:
- Valor zero: 30/12/1899 0h GMT 00:00
- Armazenado em dias fracionados (precisão de milissegundos)
- Limites: -657434.0 (01/01/0100 12h), 2958465.9999999 (31/12/9999 23:59:59.999) (Bem na verdade acho que dá pra ultrapassar estes valores sem problemas no Delphi, parece que o limite refere-se apenas à especificação)
No java, a classe java.util.Date armazena a data no padrão UTC usado pelo Unix, com as seguintes características:
- Valor zero: 1/1/1970 0h GMT 00:00
- Armazenado em milissegundos inteiros
- Limites: São milhões de anos em ambos os sentidos, algo assim
Transformação Mágica
Bem após queimar o tico e o teco cheguei na feliz conclusão que são necessárias apenas duas linhas para fazer a conversão, uma para a conversão de Java para Delphi e outra para a conversão contrária. Para tal devemos considerar os dias passados entre os respectivos zeros, 30/12/1899 e 1/1/1970. São 25569 dias, seguindo o calendário gregoriano. Devemos considerar também os milissegundos existentes em um dia, 24 * 60 * 60 * 1000 = 86400000. As fórmulas ficam assim (onde Delphi é um double que representa os dias TDateTime e Java um long que representa os milissegundos UTC):
Exemplo de conversão para a data 1/1/1970 23:59:59.999 GMT 00:00:
Bom ainda falta implementar isso mas fiquei muito contente quando meus neurônios me contaram que seria apenas uma linha para cada conversão
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/03/2005 13:10:37
|
Dharis
JavaBaby
![[Avatar]](/images/avatar/c8fc7f0b3fb2858030de9.gif)
Membro desde: 12/11/2003 16:06:56
Mensagens: 99
Localização: Rio Branco, Acre
Offline
|
renato3110 wrote:Aliás no MySQL tem uma coisa muito louca: ÀS VEZES ele PERMITE chaves primárias IGUAIS e ÀS VEZES NÃO, sem nenhuma explicação aparente!!! Esse campo de data que é um float no formato do Delphi é que é a chave primária
O MySQL não permite chaves primárias iguais.
A questão é saber se os valores de pontos flutuantes são exatamente iguais, erros de precisão podem ocorrer.
Se você ver em Comparing floating point numbers, comparações == entre valores de pontos flutuantes podem ser falsas, mesmo você acreditando que os números são os mesmos.
|
Dharis |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/03/2005 13:56:46
|
renatosilva
GUJ Master
Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline
|
Dharis, usei o MySQL-Front e cadastrei manualmente no banco, copiei o valor 38411,9890920833 e consegui criar um novo registro, mas tem hora que não dá!!!!
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/03/2005 19:56:05
|
renatosilva
GUJ Master
Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline
|
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/03/2005 09:56:09
|
renatosilva
GUJ Master
Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline
|
Uma dúvida: quando eu converto um double para long no método javaDate acima, ele arredonda o valor ou trunca? Exemplo:
double 1,5 trunca para 1 ou arredonda para 1 ou 2?
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/03/2005 10:20:31
|
thingol
Moderador
Membro desde: 29/07/2004 16:10:13
Mensagens: 17539
Offline
|
O "cast" de double para long trunca (para baixo, se for um número positivo, e para cima, se for um número negativo.)
(long) 1.3 -> 1
(long) 1.5 -> 1
(long) 1.51 -> 1
(long) -1.3 -> -1
(long) -1.5 -> -1
(long) -1.51 -> -1
Eu digo que é "para cima", no caso de números negativos, porque -1.5 é menor que -1.
|
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/03/2005 10:55:25
|
renatosilva
GUJ Master
Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline
|
Sacado, então tem como usar uma função de arredondamento? Porque as fórmulas não podem truncar, elas têm que arredondar!
|
|
|
 |
|
|