it-swarm-pt.tech

java data e hora sql

Quando insiro um SQL DateTime no banco de dados, recebo 2007-02-07 12:00:00.00

Mas eu criei o objeto Date assim: 2007-02-07 17:29:46.00

Como obter o valor dos segundos no banco de dados. Sempre muda de volta para 12:00:00.00

date.setYear(Integer.valueOf(parsedDate[2].replaceAll(" ", "")) - 1900);
date.setMonth(Integer.valueOf(parsedDate[0].replaceAll(" ", "")));
date.setDate(Integer.valueOf(parsedDate[1].replaceAll(" ", "")));
...
Java.sql.Date sqlDate = new Java.sql.Date(date.getTime());

Devo usar algum formatador?

15
Elbek

Java.sql.Date representa uma data, não uma data e hora. De os documentos :

Para estar em conformidade com a definição de SQL DATE, os valores de milissegundos agrupados por uma instância Java.sql.Date devem ser 'normalizados', definindo as horas, minutos, segundos e milissegundos para zero no fuso horário específico ao qual a instância está associada .

Se você deseja armazenar uma data e hora, procure outro tipo, por exemplo Java.sql.Timestamp . EDIT: Isso não está sugerindo que você use um tipo de coluna TIMESTAMP - como diz paulsm4 nos comentários, isso é uma coisa diferente. No entanto, tanto quanto posso ver, o JDBC suporta apenas:

  • Date (não, você também quer um tempo)
  • Time (não, você também quer um encontro)
  • Timestamp (inclui uma data e hora, mas você não deseja a semântica TIMESTAMP SQL)

Eu esperaria usando o tipo Java Timestamp _ com uma coluna DATETIME para funcionar, embora sem o nível de precisão que Timestamp fornece.

EDIT: Após um pouco mais de pesquisa, parece que você pode querer usar o Java.sql.Time, mas com parâmetros especiais de driver - pelo menos se você estiver usando o driver da Microsoft. Consulte estes documentos em configurando o JDBC para obter mais informações.

30
Jon Skeet

tl; dr

Você provavelmente está confuso por não entender que Java.util.Date é um tipo de data e hora, enquanto sua subclasse Java.sql.Date finge como uma classe somente para data, mas na verdade tem sua hora do dia definida como zero. Design horrível. Evite essas duas classes completamente. Use Java.time somente classes.

Para uma coluna somente de data em seu banco de dados, defina a coluna como o tipo DATE do padrão SQL.

myPreparedStatement.setObject(
    … ,
    LocalDateTime.parse( "2007-02-07 17:29:46.00".replace( " " , "T" ) )
    .toLocalDate()
)

Java.time

A abordagem moderna usa as classes Java.time adicionadas a Java 8 e posterior.

Quando insiro um SQL DateTime no banco de dados, obtenho 07-02-2007 12: 00: 00.00

Não existe um tipo padrão SQL como DateTime, nem classe em Java. Então, eu não conheço sua intenção lá.

Quanto à sequência de entrada, 2007-02-07 17:29:46.00, analise isso como um LocalDateTime porque não possui nenhum indicador de fuso horário ou deslocamento do UTC.

Esse formato de estilo SQL quase cumpre o padrão ISO 8601 . Para cumprir totalmente, substitua o ESPAÇO no meio por T. As classes Java.time usam os formatos ISO 8601 por padrão ao analisar/gerar cadeias.

String input = "2007-02-07 17:29:46.00".replace( " " , "T" ) ;

Parse.

LocalDateTime ldt = LocalDateTime.parse( input ) ;

Um LocalDateTime não representa um momento, é não um ponto na linha do tempo. Representa momentos potenciais ao longo de um intervalo de cerca de 26 a 27 horas.

O SQL padrão oferece um tipo de dados para esse valor, TIMESTAMP WITHOUT TIME ZONE.

Objetos inteligentes, não cordas idiotas

Toda a sua abordagem é equivocada, disputando texto e usando as classes de data e hora herdadas. Em vez disso, troque objetos Java.time.

No JDBC 4.2, você nunca precisa usar os tipos Java.sql antigos e problemáticos, como Java.sql.Date ou Java.sql.Timestamp. Você pode trocar diretamente objetos Java.time com seu banco de dados através dos métodos setObject/getObject.

myPreparedStatement.setObject( … , ldt ) ;

E recuperação.

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;

Se você estiver tentando trabalhar com valores somente de data, use o tipo padrão SQL DATE e o Java classe LocalDate.

LocalDate ld = ldt.toLocalDate() ;
myPreparedStatement.setObject( … , ld ) ;

Como obter o valor dos segundos no banco de dados

Não sei o que você quer dizer com "valor dos segundos".

Talvez você queira uma contagem de segundos a partir do referência da época do primeiro momento de 1970 no UTC.

long secondsSinceEpoch = ldt.toEpochSecond() ;

Se seu objetivo era apenas instanciar um Java.sql.Date, não se preocupe. Nunca use essa classe novamente. Mas, para sua informação, seu problema específico provavelmente é um efeito colateral do péssimo design usado para essa classe. O Java.sql.Date classe herda de Java.util.Date que é um tipo de data e hora. O Java.sql.Date class finge como um valor somente para data, mas na verdade tem seu horário definido como 00:00:00. Pior ainda, a documentação nos diz para ignorar o fato de ser uma subclasse. Não se preocupe em tentar entender; basta usar Java.time em vez disso.

Se você estiver tentando trabalhar apenas com a hora do dia, extraia um objeto LocalTime.

LocalTime lt = ldt.toLocalTime() ;

Se você deseja definir a hora do dia como zeros, provavelmente deseja um valor apenas de data. Nesse caso, use a classe LocalDate para um valor de data sem uma hora do dia e sem um fuso horário.

LocalDate ld = ldt.toLocalDate() :

Se você deseja o primeiro momento do dia nessa data, ligue para LocalDate::atStartOfDay .

LocalDateTime ldtStart = ldt.toLocalDate().atStartOfDay() ;

CUIDADO: Se você está tentando rastrear momentos reais, pontos específicos na linha do tempo, todo esse código acima está errado. Pesquise Estouro de Pilha para aprender sobre as classes Instant, ZoneId e ZonedDateTime. Pesquise o Stack Overflow e o dba.StackExchange.com para aprender sobre o tipo de padrão SQL TIMESTAMP WITH TIME ZONE.


Sobre Java.time

A estrutura Java.time é incorporada ao Java 8 e posterior. Essas classes substituem o antigo e problemático legado classes de data e hora, como Java.util.Date , Calendar , & SimpleDateFormat .

O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes Java.time .

Para saber mais, consulte o Oracle Tutorial . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 31 .

Você pode trocar Java.time objetos diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de Java.sql.* Aulas.

Onde obter as classes Java.time?

O projeto ThreeTen-Extra estende o Java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao Java.time. Você pode encontrar algumas classes úteis aqui, como Interval , YearWeek , YearQuarter e mais .

2
Basil Bourque