Java Timestamp - Como posso criar um Timestamp com a data 23/09/2007?

100

Como posso criar um Timestamp com a data 23/09/2007?

pigouina
fonte

Respostas:

154

Por Timestamp, eu presumo que você queira dizer java.sql.Timestamp. Você notará que esta classe possui um construtor que aceita um longargumento. Você pode analisar isso usando a DateFormatclasse:

DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = dateFormat.parse("23/09/2007");
long time = date.getTime();
new Timestamp(time);
Adam Paynter
fonte
1
O formato de data ISO normal é aaaa-MM-dd, caso contrário, ótimo!
vidstige
1
novo carimbo de data / hora (hora); dando erro que nenhum construtor como este leva um valor longo :(
Bhanu Sharma
1
@Bhanu Os documentos mostram que isso tem um valor longo e parece funcionar corretamente: docs.oracle.com/javase/7/docs/api/java/sql/…
Hazok
Para sua informação, as classes de data e hora terrivelmente problemáticas como java.util.Date, java.util.Calendare java.text.SimpleDateFormatagora são legadas , suplantadas pelas classes java.time construídas no Java 8 e posterior. Veja o Tutorial da Oracle .
Basil Bourque
121

Que tal isso?

java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");
pigouina
fonte
1
Timestamp timestamp = Timestamp.valueOf ("2007-09-23 10: 10: 10.0"); está mostrando que o método valueOf é indefinido para o tipo Timestamp em jDK 7
Ashish Ratan
novo carimbo de data / hora (hora); dando erro que nenhum construtor como este leva um valor de string :(
Bhanu Sharma
@Bhanu O construtor leva o tempo unix em milissegundos. Use o método estático valueOf se quiser obter um carimbo de data / hora de uma string.
Hazok
4
Esta parece ser a melhor resposta para a pergunta.
Hazok
1
A melhor resposta é Date, que está obsoleto, é uma má prática usá-lo. Esta resposta é melhor. Obrigado
Alberici,
18

O que você quer dizer com carimbo de data / hora? Se você quer dizer milissegundos desde a época do Unix:

GregorianCalendar cal = new GregorianCalendar(2007, 9 - 1, 23);
long millis = cal.getTimeInMillis();

Se você quiser um objeto java.sql.Timestamp real:

Timestamp ts = new Timestamp(millis);
Matthew Flaschen
fonte
2
ERRADO e não compila! Erro de compilação: 09 é um número octal, mas 9 está fora do intervalo para octais. Erro lógico: o mês é baseado em 0, você receberá 23 DE OUTUBRO de 2007
user85421
Não consigo obter um erro lógico se não compilar. :) Sério, boas pegadas, Carlos. O octal eu peguei antes, mas colei errado de qualquer maneira. :(
Matthew Flaschen
Na verdade, o construtor Timestamp está obsoleto, mas você pode usar o método Timestamp.valueOf ()
Shiva Komuravelly
@ShivaKomuravelly nem todos os construtores de timestamp estão obsoletos e, pelo menos, não leva tanto tempo quanto milissegundos, o construtor que leva a data como argumento está obsoleto
sem nome
E há uma constante para isso (em vez de mês = 9):Calendar.SEPTEMBER
Guillaume Husta
11

tl; dr

java.sql.Timestamp.from (
    LocalDate.of ( 2007 , 9 , 23 )
             .atStartOfDay( ZoneId.of ( "America/Montreal" ) )
             .toInstant()
)

java.time

Vamos atualizar esta página mostrando o código usando a estrutura java.time construída no Java 8 e posterior.

Essas novas classes são inspiradas no Joda-Time , definido pela JSR 310 e estendido pelo projeto ThreeTen-Extra . Eles suplantam as classes data-hora notoriamente problemáticas, agrupadas com as primeiras versões do Java.

Em java.time, Instanté um momento na linha do tempo em UTC. A ZonedDateTimeé um Instant ajustado em um fuso horário ( ZoneId).

O fuso horário é crucial aqui. Uma data de September 23, 2007não pode ser traduzida em um momento na linha do tempo sem aplicar um fuso horário. Considere que um novo dia amanhece mais cedo em Paris do que em Montreal, onde ainda é “ontem”.

Além disso, um java.sql.Timestamp representa a data e a hora do dia. Portanto, devemos injetar uma hora do dia para acompanhar a data. Presumimos que você deseja o primeiro momento do dia como a hora do dia. Observe que esta nem sempre é a hora 00:00:00.0devido ao horário de verão e possivelmente outras anomalias.

Observe que, ao contrário da classe java.util.Date antiga e ao contrário do Joda-Time, os tipos java.time têm uma resolução de nanossegundos em vez de milissegundos. Isso corresponde à resolução de java.sql.Timestamp.

Observe que o java.sql.Timestamp tem o péssimo hábito de aplicar implicitamente o fuso horário padrão atual da JVM ao valor de data e hora ao gerar uma representação de string por meio de seu toStringmétodo. Aqui você vê meu America/Los_Angelesfuso horário aplicado. Em contraste, as classes java.time são mais lógicas, usando formatos padrão ISO 8601 .

LocalDate d = LocalDate.of ( 2007 , 9 , 23 ) ;
ZoneId z = ZoneId.of ( "America/Montreal" ) ;
ZonedDateTime zdt = d.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;
java.sql.Timestamp ts = java.sql.Timestamp.from ( instant ) ;

Despeje para o console.

System.out.println ( "d: " + d + " = zdt: " + zdt + " = instant: " + instant + " = ts: " + ts );

Quando corre.

d: 2007-09-23 = zdt: 2007-09-23T00: 00-04: 00 [America / Montreal] = instant: 2007-09-23T04: 00: 00Z = ts: 2007-09-22 21:00: 00,0

A propósito, a partir do JDBC 4.2, você pode usar os tipos java.time diretamente. Não há necessidade java.sql.Timestamp.

  • PreparedStatement.setObject
  • ResultSet.getObject

Sobre java.time

A estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como java.util.Date, Calendar, e 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 tutorial Oracle . E pesquise no Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .

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

Onde obter as classes java.time?

O projeto ThreeTen-Extra 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 .

Basil Bourque
fonte
3
Gostaria de saber como posso obter OP ou mods para marcar sua resposta como a correta. A resposta aceita está tão desatualizada.
sttaq
Muito bom, exceto por um erro de digitação. asStartOfDay () deve ser atStartOfDay ().
Tullochgorum
@Tullochgorum Fixed. Obrigado. Para sua informação, no Stack Overflow, você está convidado a fazer essas edições você mesmo, se quiser.
Basil Bourque
5

Você também pode fazer o seguinte:

// untested
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 23);// I might have the wrong Calendar constant...
cal.set(Calendar.MONTH, 8);// -1 as month is zero-based
cal.set(Calendar.YEAR, 2009);
Timestamp tstamp = new Timestamp(cal.getTimeInMillis());
Alex
fonte
2
ERRADO: tente um System.out.println do resultado! Você obterá algo como: "2009-10-23 15: 26: 56.171" O mês é baseado em 0, então 9 é outubro!
user85421
Eu sabia que uma dessas constantes era baseada em zero, obrigado. Postagem atualizada.
Alex
1
Ah, e coloquei 'não testado' :)
Alex
4

De acordo com a API, o construtor que aceitaria ano, mês e assim por diante foi descontinuado. Em vez disso, você deve usar o Construtor que aceita um longo. Você pode usar uma implementação de Calendário para construir a data desejada e acessar a representação de tempo como um longo, por exemplo, com o método getTimeInMillis .

Philipp
fonte
1

Para completar, também uma solução com Joda-Time versão 2.5 e sua DateTimeclasse:

new Timestamp(new DateTime(2007, 9, 23, 0, 0, DateTimeZone.forID( "America/Montreal" )).getMillis())
user152468
fonte
1
Boa resposta, mas você perdeu uma peça crucial : fuso horário . Se você omitir um fuso horário, o fuso horário padrão atual da JVM será aplicado ao DateTimeobjeto. Isso significa que seus resultados irão variar em vários computadores ou configuração do sistema operacional host ou configurações de JVM. Para resultados previsíveis, passe um fuso horário para esse DateTimeconstrutor. Escolha o nome do fuso horário adequado para sua intenção. Por exemplo, DateTimeZone.forID( "America/Montreal" )ou DateTimeZone.UTC.
Basil Bourque
Esse código pode ser mais breve. Não há necessidade de converter para java.util.Date para obter e passar os milissegundos desde a época . Basta perguntar ao DateTimeobjeto seus milissegundos desde a época. Substitua .toDate().getTime()por .getMillis().
Basil Bourque
@BasilBourque Dependendo das circunstâncias, você pode querer deixar de fora o fuso horário para ter resultados previsíveis. "No seu fuso horário atual" pode ser um resultado perfeitamente razoável e previsível. Por que codificar um fuso horário ou pedir aos usuários que definam um fuso horário manualmente quando o computador já tem um fuso horário definido? Certamente eu ficaria muito surpreso se um aplicativo no meu computador começasse a exibir datas ajustadas para o fuso horário da América / Montreal.
Dan Carter
@dancarter Omitir o fuso horário opcional leva à confusão. A omissão aumenta a ambigüidade de (a) o programador pretendia confiar no padrão implícito ou (b) o programador deixou de considerar os problemas de fuso horário (como é muito comum). Se você realmente deseja usar o fuso horário padrão atual da JVM, diga isso explicitamente chamando DateTimeZone.getDefault()e passando o resultado como o argumento opcional. (A propósito, idem para a Locale.getDefault()mesma questão sobre a ambiguidade de argumentos opcionais.)
Basil Bourque
-1

Uma resposta mais geral seria importar java.util.Date, então quando você precisar definir um timestampigual para a data atual, simplesmente defina-o como igual a new Date().

CSquid
fonte
porque ** Data ("string"); ** está obsoleto
Ashish Ratan