Pergunta

Estou trabalhando com webservices, inserindo registros, que retornam um valor de timestamp no tipo XMLGregorianCalendar.Preciso transformá-lo em um valor java.sql.Timestamp, então uso uma função como esta.

public static java.sql.Timestamp getSqlTimeStamp(XMLGregorianCalendar xgc) {
    if (xgc == null) {
        return null;
    } else {
        return new Timestamp(xgc.toGregorianCalendar().getTime().getTime());
    }
}
Timestamp timestamp=getSqlTimeStamp(ExitInXMLGregor.getTimestamp());

Meu problema é que no servidor o valor do timestamp quando insiro um registro fica assim:03-10-2012T19:23:22.342+02:00

Mas quando faço minha conversão de tipo, obtenho o valor do carimbo de data/hora assim:03-10-2012T17:23:22.342

O tempo no servidor (onde está localizado o webservice) é 2h a mais que o meu locale, e por algum motivo, obtenho o horário do meu locale de inserção, após transformá-lo.O problema é que preciso muito obter o horário do servidor, pois no BD o valor do timestamp coincide com o do servidor, e estou tendo problemas na operação de atualização, devido aos valores diferentes do timestamp.

Por favor, eu apreciaria qualquer tipo de ajuda.obrigado!

Editar:Eu meio que encontro uma solução, mas não é exatamente o que preciso.Quando converto meu timestamp no formato java.sql.Timestamp para XMLGregorian eu configuro o timeZone do servidor (setTimeZone(TimeZone.getTimeZone("GMT+02:00"))).Isso realmente funciona, mas está longe da solução ideal (Pode acontecer que o fuso horário ou até mesmo o servidor mude) Seria ótimo saber neste ponto o fuso horário do servidor dinamicamente, mas não sei como. .

public static XMLGregorianCalendar getXMLGregorianCalendar(Timestamp timestamp)
        throws BaseException {
    try {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTimeZone(TimeZone.getTimeZone("GMT+02:00"));
        gc.setTimeInMillis(timestamp.getTime());
        return DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
    } catch (DatatypeConfigurationException ex) {
        throw new BaseException(ex);
    }
}
Foi útil?

Solução

Suspeito que o carimbo de data/hora especifica a hora correta, mas não é exibido com o fuso horário correto.2012-10-03T17:23:22.342 é o mesmo que 2012-10-03T19:23:22.342+02:00, assumindo que o fuso horário (oculto) do primeiro é +00:00.

Outras dicas

dr.

  • Ambas as strings representam o mesmo momento, simplesmente ajustadas para um fuso horário, sem anotar o deslocamento de UTC.
  • Evite essa confusão sempre incluindo as informações de deslocamento e zona nessas strings.
  • Usar moderno java.time classes que substituem as classes legadas problemáticas.(Instant, não Timestamp)

Código de exemplo.

myPreparedStatement.setObject( 
    … , 
    myXMLGregorianCalendar  // If forced to work with a `javax.xml.datatype.XMLGregorianCalendar` object rather than a modern java.time class…
    .toGregorianCalendar()  // …convert to a `java.util.GregorianCalendar`, and then…
    .toZonedDateTime()      // …convert to modern `java.time.ZonedDateTime` class.
    .toInstant()            // Adjust to UTC by extracting an `Instant` object.
)

Recuperando de um banco de dados, a partir do JDBC 4.2 e posterior.

Instant instant = myResultSet.getObject( … , Instant.class ) ;

java.time

Enquanto o correta aceita Resposta de Robert Tupelo-Schneck diz, parece que está tudo bem porque ambas as strings representam o mesmo momento, mas ajustadas em um fuso horário diferente com um deslocamento diferente do UTC.O problema é que uma dessas duas strings não possui um indicador de seu deslocamento em relação ao UTC.

Tal omissão é uma má prática, pois cria esta confusão.Sempre inclua o deslocamento do UTC, a menos que tenha certeza absoluta de que o contexto deixa o deslocamento/zona claro.

Trabalhar em UTC

Trabalhar em UTC evita esse tipo de confusão.Geralmente é melhor trabalhar, armazenar e trocar valores de data e hora em UTC.Ajuste do UTC para um fuso horário apenas para apresentação ao usuário ou quando exigido pela lógica de negócios.

Além disso, você está usando classes antigas terrivelmente problemáticas que agora foram suplantadas pelo java.time Aulas.Converta seu XMLGregorianCalendar para java.time.ZonedDateTime.

ZonedDateTime zdt = myXMLGregorianCalendar.toGregorianCalendar().toZonedDateTime() ;

Ajuste para UTC extraindo um Instant objeto.

Instant instant = zdt.toInstant() ;

A partir do JDBC 4.2 e posterior, você pode trocar diretamente java.time objetos com o banco de dados.Não há necessidade de usar o legado java.sql.Timestamp aula novamente.

myPreparedStatement.setObject( … , instant ) ;

Recuperação:

Instant instant = myResultSet.getObject( … , Instant.class ) ;

Ajuste do UTC para algum fuso horário específico se quiser ver o mesmo momento usando o horário do relógio de parede usado pelas pessoas de uma região específica.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

Converter

Se você precisar interagir com algum código antigo que exija um java.sql.Timestamp, você pode converter para frente e para trás com java.time.Instant.Chame novos métodos de conversão adicionados às classes antigas.

java.sql.Timestamp ts = java.sql.Timestamp.from( instant ) ;

Indo na outra direção.

Instant instant = ts.toInstant() ;

Veja também minha resposta para uma pergunta semelhante.


Sobre java.time

O java.time framework é integrado ao Java 8 e posterior.Essas aulas substituem as velhas e problemáticas legado classes de data e hora, como java.util.Date, Calendar, & SimpleDateFormat.

O Hora Joda projeto, agora em Modo de manutenção, aconselha a migração para o java.time Aulas.

Para saber mais, consulte o Tutorial Oráculo.E pesquise no Stack Overflow muitos exemplos e explicações.A especificação é JSR 310.

Você pode trocar java.time objetos diretamente com seu banco de dados.Use um Driver JDBC em conformidade com JDBC4.2 ou mais tarde.Não há necessidade de cordas, não há necessidade de java.sql.* Aulas.

Onde obter as classes java.time?

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top