Como converter java.util.Date em java.sql.Date?

453

Estou tentando usar um java.util.Datecomo entrada e, em seguida, criando uma consulta com ele - então preciso de umjava.sql.Date .

Fiquei surpreso ao descobrir que ela não podia fazer a conversão de forma implícita ou explícita - mas nem sei como faria isso, pois a API Java ainda é relativamente nova para mim.

David Ackerman
fonte
Você pode encontrar um problema semelhante aqui stackoverflow.com/questions/12131068/…
Lem
Para mim, acabei não precisando me converter. Havia um import java.sql.*no meu código, substituindo o java.util.date e, portanto, causando problemas ao atribuir valores de data que estavam bem com o último, mas não o primeiro. HTH
HumanInDisguise
1
@DavidAckerman Você entende que um java.util.Date é uma data e uma hora do dia, mas um java.sql.Date é apenas uma data sem uma hora do dia? (Na verdade, existe uma hora do dia, mas isso é ignorado, um mau hack de um design de classe) No SQL, DATEsignifica apenas data.
Basil Bourque
2
Na verdade, eu não estava ciente das nuances de 2009 e, como essa pergunta é tão popular, mudei a resposta aceita para uma que seja mais moderna e completa. Obrigado a todos por sua contribuição!
David Ackerman

Respostas:

89

tl; dr

Como converter java.util.Date em java.sql.Date?

Não. Ambas as classes estão obsoletas.

  • Use as classes java.time em vez do legado java.util.Datee java.sql.Datecom o JDBC 4.2 ou posterior.
  • Converta de / para java.time se estiver operando com código ainda não atualizado para java.time.

Exemplo de consulta com PreparedStatement.

myPreparedStatement.setObject( 
     ,                                         // Specify the ordinal number of which argument in SQL statement.
    myJavaUtilDate.toInstant()                  // Convert from legacy class `java.util.Date` (a moment in UTC) to a modern `java.time.Instant` (a moment in UTC).
        .atZone( ZoneId.of( "Africa/Tunis" ) )  // Adjust from UTC to a particular time zone, to determine a date. Instantiating a `ZonedDateTime`.
        .toLocalDate()                          // Extract a date-only `java.time.LocalDate` object from the date-time `ZonedDateTime` object.
)

Substituições:

  • Instantem vez de java.util.Date
    Ambos representam um momento no UTC. mas agora com nanossegundos em vez de milissegundos.
  • LocalDateem vez de java.sql.Date
    Ambos representam um valor somente de data sem uma hora do dia e sem um fuso horário.

Detalhes

Se você estiver tentando trabalhar com valores somente de data (sem hora do dia, sem fuso horário), use a LocalDateclasse em vez de java.util.Date.

Tabela de tipos de data e hora em Java (herdado e moderno) e no padrão SQL.

java.time

No Java 8 e posterior, as classes antigas de data e hora problemáticas incluídas nas versões anteriores do Java foram substituídas pelo novo pacote java.time . Consulte o Tutorial do Oracle . Grande parte da funcionalidade foi portada para Java 6 e 7 no ThreeTen-Backport e posteriormente adaptada ao Android no ThreeTenABP .

Um tipo de dados SQL DATE deve ser apenas de data, sem hora do dia e sem fuso horário. Java nunca teve exatamente essa classe † até java.time.LocalDateno Java 8. Vamos criar esse valor obtendo a data de hoje de acordo com um fuso horário específico (o fuso horário é importante para determinar uma data em que um novo dia amanhece mais cedo em Paris do que em Montreal, por exemplo).

LocalDate todayLocalDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );  // Use proper "continent/region" time zone names; never use 3-4 letter codes like "EST" or "IST".

Neste ponto, podemos terminar. Se o seu driver JDBC estiver em conformidade com as especificações do JDBC 4.2 , você poderá passar uma LocalDatevia setObjecta PreparedStatementpara armazenar em um campo SQL DATE.

myPreparedStatement.setObject( 1 , localDate );

Da mesma forma, use ResultSet::getObjectpara buscar de uma coluna SQL DATE para um LocalDateobjeto Java . A especificação da classe no segundo argumento torna seu código seguro .

LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );

Em outras palavras, toda essa pergunta é irrelevante no JDBC 4.2 ou posterior.

Se o seu driver JDBC não funcionar dessa maneira, você precisará voltar a converter para os tipos java.sql.

Converta em java.sql.Date

Para converter, use novos métodos adicionados às classes de data e hora antigas. Podemos ligar java.sql.Date.valueOf(…)para converter um LocalDate.

java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );

E indo na outra direção.

LocalDate localDate = sqlDate.toLocalDate();

Convertendo de java.util.Date

Embora você deva evitar o uso das classes de data e hora antigas, você pode ser forçado a trabalhar com código existente. Nesse caso, você pode converter de / para java.time.

Passe pela Instantclasse, que representa um momento na linha do tempo no UTC. Uma Instantidéia é semelhante a uma java.util.Date. Mas observe que Instanttem uma resolução de até nanossegundos, enquanto java.util.Dateapenas milissegundos resolução.

Para converter, use novos métodos adicionados às classes antigas. Por exemplo, java.util.Date.from( Instant )e java.util.Date::toInstant.

Instant instant = myUtilDate.toInstant();

Para determinar uma data, precisamos do contexto de um fuso horário. Por um determinado momento, a data varia em todo o mundo por fuso horário. Aplique a ZoneIdpara obter a ZonedDateTime.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
LocalDate localDate = zdt.toLocalDate();

† A classe java.sql.Date finge ser apenas de data sem uma hora do dia, mas na verdade faz uma hora do dia, ajustada para a meia-noite. Confuso? Sim, as antigas classes de data e hora estão uma bagunça.


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, eSimpleDateFormat .

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 do Oracle . E procure 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 strings, não há necessidade de java.sql.*classes.

Onde obter as classes java.time?

Tabela de qual biblioteca java.time a ser usada com qual versão do Java ou Android

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 .

Basil Bourque
fonte
478

Deixa pra lá....

public class MainClass {

  public static void main(String[] args) {
    java.util.Date utilDate = new java.util.Date();
    java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
    System.out.println("utilDate:" + utilDate);
    System.out.println("sqlDate:" + sqlDate);

  }

}

explica isso. O link é http://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htm

David Ackerman
fonte
34
Esta não é uma conversão explícita! No Javadoc: "Se o valor em milissegundos fornecido contiver informações de hora, o driver definirá os componentes de hora para a hora no fuso horário padrão (o fuso horário da Java virtual machine executando o aplicativo) que corresponde a zero GMT." Portanto, independentemente do seu tempo no seu java.util.Date, ele será inserido como 00:00:00 em uma coluna com o tipo de dados definido como DATE.
1
@ David Ackerman ..... esse método retorna epochsecondsmilissegundos depois 1,JAN,1970. Mas e se quisermos armazenar a data de uma pessoa antes dessa data ... ou algo parecido com0000-00-00 as default
Arjun KP
31
No meu caso, a resposta correta é <code> java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp (utilDate.getTime ()); </code>, porque preserva os campos de tempo.
Alberto de Paola
2
@ wired00 Sim, as antigas classes de data e hora incluídas nas versões anteriores do Java são uma bagunça , mal projetadas, incluindo alguns hacks rudes. Sempre que possível, tente usar a nova estrutura java.time no Java 8 e posterior. Essas novas classes substituem as antigas. As classes java.time e as classes antigas possuem alguns métodos convenientes de conversão para frente e para trás - úteis enquanto esperamos que os drivers JDBC sejam atualizados para utilizar diretamente os novos tipos java.time.
Basil Bourque
1
@ wired00 Veja minha nova resposta nesta pergunta para saber como usar o java.time. Pesquise também o StackOverflow para muitos outros exemplos.
Basil Bourque
39

Com a outra resposta, você pode ter problemas com as informações de horário (compare as datas com resultados inesperados!)

Eu sugiro:

java.util.Calendar cal = Calendar.getInstance();
java.util.Date utilDate = new java.util.Date(); // your util date
cal.setTime(utilDate);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);    
java.sql.Date sqlDate = new java.sql.Date(cal.getTime().getTime()); // your sql date
System.out.println("utilDate:" + utilDate);
System.out.println("sqlDate:" + sqlDate);
Mauretto
fonte
5
Se ele estiver usando java.sql.Date para uma coluna Data em um banco de dados, as informações de horário serão truncadas. Você superengenhou a solução na minha opinião.
darioo
4
Sim, talvez eu tenha feito. Às vezes, preciso comparar o java.sql.Data com a data atual e imho essa é a melhor maneira. Espero que possa ajudar.
9788
FYI, os terrivelmente problemáticas aulas em tempo data antigas, tais como java.util.Date, java.util.Calendare java.text.SimpleDateFormatestão agora legado , suplantado pelos java.time classes internas em Java 8 e posterior. Consulte o Tutorial da Oracle .
Basil Bourque
Claro, este tema foi cerca de 10 anos atrás, pré-java 8.
mauretto
26

Essa função retornará uma data SQL convertida do objeto de data java.

public java.sql.Date convertJavaDateToSqlDate(java.util.Date date) {
    return new java.sql.Date(date.getTime());
}
chetan
fonte
18

A conversão java.util.Datapara java.sql.Dataperderá hora, minuto e segundo. Então, se for possível, sugiro que você use java.sql.Timestampassim:

prepareStatement.setTimestamp(1, new Timestamp(utilDate.getTime()));

Para mais informações, você pode verificar esta pergunta .

shellbye
fonte
16

No meu caso, escolher a data do JXDatePicker (java calender) e armazená-la no banco de dados como tipo de data SQL, abaixo funciona bem.

java.sql.Date date = new java.sql.Date(pickedDate.getDate().getTime());

onde pickingDate é objeto de JXDatePicker

Jack Jay
fonte
5

Essa função retornará uma data SQL convertida do objeto de data java.

public static java.sql.Date convertFromJAVADateToSQLDate(
            java.util.Date javaDate) {
        java.sql.Date sqlDate = null;
        if (javaDate != null) {
            sqlDate = new Date(javaDate.getTime());
        }
        return sqlDate;
    }
Tanmay kumar shaw
fonte
3

Formate seu java.util.Date primeiro. Em seguida, use a data formatada para obter a data em java.sql.Date

java.util.Date utilDate = "Your date"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
final String stringDate= dateFormat.format(utilDate);
final java.sql.Date sqlDate=  java.sql.Date.valueOf(stringDate);
Hackfield
fonte
2

Aqui o exemplo de conversão de Data do Util para Data do SQL e esse é um exemplo que eu estou usando no meu projeto. Também pode ser útil para você.

java.util.Date utilStartDate = table_Login.getDob();(orwhat ever date your give form obj)
java.sql.Date sqlStartDate = new java.sql.Date(utilStartDate.getTime());(converting date)
Kishan Bheemajiyani
fonte
2

Eu sou um novato: depois de muito correr isso funcionou. O pensamento pode ser útil

     String bufDt =  bDOB.getText();  //data from form
     DateFormat dF = new SimpleDateFormat("dd-MM-yyyy"); //data in form is in this format
     Date bbdt = (Date)dF.parse(bufDt);  // string data is converted into java util date
     DateFormat dsF = new SimpleDateFormat("yyyy-MM-dd"); //converted date is reformatted for conversion to sql.date
     String ndt = dsF.format(bbdt); // java util date is converted to compatible java sql date
     java.sql.Date sqlDate=  java.sql.Date.valueOf(ndt);  // finally data from the form is convered to java sql. date for placing in database
PKSawmy
fonte
FYI, os terrivelmente problemáticas aulas em tempo data antigas, tais como java.util.Date, java.util.Calendare java.text.SimpleDateFormatestão agora legado , suplantado pelos java.time classes internas em Java 8 e posterior. Consulte o Tutorial da Oracle .
Basil Bourque
2
java.sql.Date sqlDate = new java.sql.Date(javaDate.getTime());

Aqui javaDate é a instância de java.util.Date

Rajeev Ranjan
fonte
1
Realmente não parece acrescentar nada de novo em comparação com as respostas de David Ackerman, chetan e Tanmay kumar shaw, não é?
Ole VV
1

Método para comparar 2 datas (util.date ou sql.date)

 public static boolean isSameDay(Date a, Date b) {
    Calendar calA = new GregorianCalendar();
    calA.setTime(a);

    Calendar calB = new GregorianCalendar();
    calB.setTime(b);

    final int yearA = calA.get(Calendar.YEAR);
    final int monthA = calA.get(Calendar.MONTH);
    final int dayA = calA.get(Calendar.DAY_OF_YEAR);

    final int yearB = calB.get(Calendar.YEAR);
    final int monthB = calB.get(Calendar.MONTH);
    final int dayB = calB.get(Calendar.DAY_OF_YEAR);

    return yearA == yearB && monthA == monthB && dayA == dayB;
}
Donovan Thomson
fonte
0

tente com isso

public static String toMysqlDateStr(Date date) {
    String dateForMySql = "";
    if (date == null) {
        dateForMySql = null;
    } else {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateForMySql = sdf.format(date);
    }

    return dateForMySql;
}
Kapil das
fonte
-1

Eu acho que a melhor maneira de converter é:

static java.sql.Timestamp SQLDateTime(Long utilDate) {
    return new java.sql.Timestamp(utilDate);
}

Date date = new Date();
java.sql.Timestamp dt = SQLDateTime(date.getTime());

Se você deseja inserir a dtvariável em uma tabela SQL, você pode:

insert into table (expireAt) values ('"+dt+"');
user6043502
fonte
1
Parece ser essencialmente o mesmo que esta resposta publicada um ano antes.
Bernhard Barker
-3

Estou usando o código a seguir, por favor, experimente

DateFormat fm= new SimpleDateFormatter();

especifique o formato da data que você deseja, por exemplo, "DD-MM_YYYY"ou 'YYYY-mm-dd' use o tipo de dados java Date como

fm.format("object of java.util.date");

então ele analisará sua data

UmeshA
fonte
-3

Você pode usar esse método para converter a data do utilitário em data do sql,

DateUtilities.convertUtilDateToSql(java.util.Date)
Emmanuel Angelo.R
fonte
Não há classe DateUtilities na biblioteca Java padrão (e eu não consigo encontrar esse método em nenhum lugar a partir de uma pesquisa rápida no Google). Se for de uma biblioteca específica, convém dizer o mesmo e incluir um link para os documentos.
Bernhard Barker
-4

Eu estava tentando a seguinte codificação que funcionou bem.

java.util.Date utilDate = novo java.util.Date ();
java.sql.Date sqlDate = novo java.sql.Date (utilDate);

PONRAJ
fonte
-8

Se você está usando o MySQL, uma coluna de data pode receber uma representação String dessa data

Então, eu usando a classe DateFormatter para formatá-lo e defini-lo como uma String na instrução sql ou instrução preparada

aqui está a ilustração do código:

private String converUtilDateToSqlDate(java.util.Date utilDate) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String sqlDate = sdf.format(utilDate);
    return sqlDate;
}

Data da string = converUtilDateToSqlDate (otherTransaction.getTransDate ());

// passa essa data na sua instrução sql

Benjamin Ndugga
fonte
14
Bem-vindo ao stackoverflow, tenho alguns comentários para sua resposta. A questão era "como converter um java.util.Date para java.sql.Date". O código que você colou formata um java.util.Date como aaaa-MM-dd. Na verdade, isso é de uso limitado nesse contexto, pois você deve passar o java.sql.Date diretamente para os drivers jdbc, em vez de fazê-lo como uma string.
jontro