Bagaimana cara mengubah java.util.Date ke java.sql.Date?

453

Saya mencoba menggunakan java.util.Dateinput sebagai dan kemudian membuat kueri dengannya - jadi saya perlu a java.sql.Date.

Saya terkejut menemukan bahwa itu tidak dapat melakukan konversi secara implisit atau eksplisit - tetapi saya bahkan tidak tahu bagaimana saya akan melakukan ini, karena Java API masih cukup baru bagi saya.

David Ackerman
sumber
Anda dapat menemukan masalah serupa di sini stackoverflow.com/questions/12131068/…
Lem
Bagi saya, ternyata saya tidak perlu bertobat. Ada import java.sql.*dalam kode saya, menimpa java.util.date dan dengan demikian menyebabkan masalah ketika menetapkan nilai tanggal yang baik-baik saja dengan yang terakhir tetapi bukan yang pertama. HTH
HumanInDisguise
1
@ Davidviderman Apakah Anda mengerti bahwa java.util.Date adalah tanggal dan waktu, tetapi java.sql.Date hanya tanggal tanpa waktu hari? (Sebenarnya ada waktu tetapi yang diabaikan, retas buruk dari desain kelas) Dalam SQL, DATEberarti hanya tanggal.
Basil Bourque
2
Saya memang tidak menyadari nuansa kembali pada '09, dan karena pertanyaan ini sangat populer, saya telah mengubah jawaban yang diterima menjadi yang lebih modern dan lengkap. Terima kasih semuanya atas masukan Anda!
David Ackerman

Jawaban:

89

tl; dr

Bagaimana cara mengubah java.util.Date ke java.sql.Date?

Jangan. Kedua kelas sudah ketinggalan zaman.

  • Gunakan kelas java.time bukan warisan java.util.Date& java.sql.Datedengan JDBC 4.2 atau yang lebih baru.
  • Konversikan ke / dari java.time jika inter-operasi dengan kode belum diperbarui ke java.time.

Contoh kueri dengan 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.
)

Penggantian:

  • Instant dari pada java.util.Date
    Keduanya mewakili momen di UTC. tapi sekarang dengan nanodetik, bukan milidetik.
  • LocalDate dari pada java.sql.Date
    Keduanya menunjukkan nilai hanya tanggal tanpa waktu dalam sehari dan tanpa zona waktu.

Detail

Jika Anda mencoba untuk bekerja dengan nilai hanya tanggal (tanpa waktu, tanpa zona waktu), gunakan LocalDatekelas daripada java.util.Date.

Tabel tipe tanggal-waktu di Jawa (baik yang lama maupun yang modern) dan dalam standar SQL.

waktu java

Di Java 8 dan yang lebih baru, kelas tanggal-waktu lama yang bermasalah yang dibundel dengan versi awal Java telah digantikan oleh paket java.time yang baru . Lihat Tutorial Oracle . Sebagian besar fungsi telah di-porting ke Java 6 & 7 di ThreeTen-Backport dan selanjutnya diadaptasi ke Android di ThreeTenABP .

Sebuah tipe data SQL DATE dimaksudkan untuk menjadi tanggal-satunya, dengan tidak ada waktu-of-hari dan tidak ada zona waktu. Java tidak pernah memiliki kelas seperti itu † sampai java.time.LocalDatedi Jawa 8. Mari kita membuat nilai seperti itu dengan mendapatkan tanggal hari ini sesuai dengan zona waktu tertentu (zona waktu penting dalam menentukan tanggal sebagai hari baru fajar lebih awal di Paris daripada di Montréal, karena contoh).

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".

Pada titik ini, kita mungkin sudah selesai. Jika driver JDBC Anda sesuai dengan spesifikasi JDBC 4.2 , Anda harus bisa mengirimkan LocalDatevia setObjectpada PreparedStatementuntuk menyimpan ke bidang SQL DATE.

myPreparedStatement.setObject( 1 , localDate );

Demikian juga, gunakan ResultSet::getObjectuntuk mengambil dari kolom SQL DATE ke LocalDateobjek Java . Menentukan kelas dalam argumen kedua membuat kode Anda aman .

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

Dengan kata lain, seluruh Pertanyaan ini tidak relevan di bawah JDBC 4.2 atau yang lebih baru.

Jika driver JDBC Anda tidak berkinerja dengan cara ini, Anda harus kembali ke konversi ke tipe java.sql.

Konversikan ke java.sql.Date

Untuk mengonversi, gunakan metode baru yang ditambahkan ke kelas tanggal-waktu yang lama. Kita dapat menelepon java.sql.Date.valueOf(…)untuk mengonversi a LocalDate.

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

Dan pergi ke arah lain.

LocalDate localDate = sqlDate.toLocalDate();

Konversi dari java.util.Date

Meskipun Anda harus menghindari menggunakan kelas waktu-tanggal yang lama, Anda mungkin dipaksa ketika bekerja dengan kode yang ada. Jika demikian, Anda dapat mengonversi ke / dari java.time.

Telusuri Instantkelas, yang mewakili momen dalam timeline di UTC. Sebuah Instantmirip ide untuk sebuah java.util.Date. Tetapi perhatikan bahwa Instantmemiliki resolusi hingga nanodetik sementara java.util.Datehanya memiliki resolusi milidetik .

Untuk mengonversi, gunakan metode baru yang ditambahkan ke kelas lama. Sebagai contoh, java.util.Date.from( Instant )dan java.util.Date::toInstant.

Instant instant = myUtilDate.toInstant();

Untuk menentukan tanggal, kita perlu konteks zona waktu. Untuk setiap momen tertentu, tanggalnya bervariasi di seluruh dunia berdasarkan zona waktu. Terapkan ZoneIduntuk mendapatkan ZonedDateTime.

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

Berpura-pura kelas † The java.sql.Date menjadi tanggal-hanya tanpa waktu-of-hari tetapi sebenarnya tidak waktu-of-hari, disesuaikan dengan waktu tengah malam. Membingungkan? Ya, kelas tanggal-waktu lama berantakan.


Tentang java.time

The java.time kerangka dibangun ke Jawa 8 dan kemudian. Kelas-kelas ini menggantikan tua merepotkan warisan kelas tanggal-waktu seperti java.util.Date, Calendar, & SimpleDateFormat.

Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .

Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasi adalah JSR 310 .

Anda dapat bertukar objek java.time secara langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu untuk string, tidak perlu untuk java.sql.*kelas.

Di mana mendapatkan kelas java.time?

Tabel mana perpustakaan java.time untuk digunakan dengan versi Java atau Android

Proyek ThreeTen-Extra memperpanjang java.time dengan kelas tambahan. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan masa depan ke java.time. Anda mungkin menemukan beberapa kelas berguna di sini seperti Interval, YearWeek, YearQuarter, dan lebih .

Basil Bourque
sumber
478

Sudahlah....

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);

  }

}

menjelaskannya. Tautannya adalah http://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htm

David Ackerman
sumber
34
Ini bukan konversi eksplisit! Dari Javadoc: "Jika nilai milidetik yang diberikan berisi informasi waktu, driver akan mengatur komponen waktu ke waktu di zona waktu default (zona waktu mesin virtual Java menjalankan aplikasi) yang sesuai dengan nol GMT." Jadi, apa pun waktu Anda di java.util.Date Anda, itu akan dimasukkan sebagai 00:00:00 di kolom dengan tipe data yang ditetapkan ke DATE.
1
@ David Ackerman ..... metode ini mengembalikan epochsecondsmilidetik yaitu setelah 1,JAN,1970. Tetapi bagaimana jika kita ingin menyimpan tanggal seseorang sebelum tanggal ini .... atau sesuatu seperti0000-00-00 as default
Arjun KP
31
Dalam kasus saya, jawaban yang benar adalah <code> java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp (utilDate.getTime ()); </code>, karena mempertahankan bidang waktu.
Alberto de Paola
2
@ wired00 Ya, kelas tanggal waktu lama yang dibundel dengan versi awal Java berantakan , dirancang dengan buruk termasuk beberapa peretasan kasar. Kapan pun memungkinkan, coba gunakan kerangka java.time baru di Java 8 dan yang lebih baru. Kelas-kelas baru ini menggantikan yang lama. Kelas java.time dan kelas lama memiliki beberapa metode kenyamanan untuk mengkonversi bolak-balik - berguna sementara kita menunggu driver JDBC diperbarui untuk secara langsung menggunakan tipe java.time yang baru.
Basil Bourque
1
@ wired00 Lihat Jawaban baru saya tentang Pertanyaan ini untuk cara menggunakan java.time. Juga cari StackOverflow untuk lebih banyak contoh.
Basil Bourque
39

Dengan jawaban lain, Anda mungkin memiliki masalah dengan info waktu (bandingkan tanggal dengan hasil yang tidak terduga!)

Saya menyarankan:

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
sumber
5
Jika dia menggunakan java.sql.Date untuk kolom Date di database, informasi waktu itu akan terpotong. Menurut saya, Anda telah merancang ulang solusi secara berlebihan.
darioo
4
Ya, mungkin saya yang melakukannya. Saya kadang-kadang perlu membandingkan java.sql.Data dengan tanggal sekarang dan imho ini adalah cara terbaik. Saya harap ini bisa membantu.
mauretto
FYI, sangat merepotkan tua kelas tanggal-waktu seperti java.util.Date, java.util.Calendar, dan java.text.SimpleDateFormatsekarang warisan , digantikan oleh java.time kelas dibangun ke Jawa 8 dan kemudian. Lihat Tutorial oleh Oracle .
Basil Bourque
Tentu saja, topik ini sekitar 10 tahun yang lalu, pra-java 8.
mauretto
26

Fungsi ini akan mengembalikan tanggal SQL yang dikonversi dari objek tanggal java.

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

Konversi java.util.Datake java.sql.Dataakan kehilangan jam, menit dan detik. Jadi jika memungkinkan, saya sarankan Anda menggunakan java.sql.Timestampseperti ini:

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

Untuk info lebih lanjut, Anda dapat memeriksa pertanyaan ini .

shellbye
sumber
16

Dalam kasus saya memilih tanggal dari JXDatePicker (kalender java) dan menyimpannya dalam database sebagai tipe tanggal SQL, di bawah ini berfungsi dengan baik ..

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

di mana pickDate adalah objek dari JXDatePicker

jack jay
sumber
5

Fungsi ini akan mengembalikan tanggal SQL yang dikonversi dari objek tanggal 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
sumber
3

Format java.util.Date Anda terlebih dahulu. Kemudian gunakan tanggal yang diformat untuk mendapatkan tanggal di 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);
ladang retas
sumber
2

Di sini contoh mengkonversi Util Date ke Sql date dan ya ini adalah salah satu contoh apa yang saya gunakan dalam proyek saya mungkin dapat membantu Anda juga.

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
sumber
2

Saya seorang pemula: setelah banyak berlarian ini berhasil. Pikiran mungkin bermanfaat

     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
sumber
FYI, sangat merepotkan tua kelas tanggal-waktu seperti java.util.Date, java.util.Calendar, dan java.text.SimpleDateFormatsekarang warisan , digantikan oleh java.time kelas dibangun ke Jawa 8 dan kemudian. Lihat Tutorial oleh Oracle .
Basil Bourque
2
java.sql.Date sqlDate = new java.sql.Date(javaDate.getTime());

Di sini javaDate adalah turunan dari java.util.Date

Rajeev Ranjan
sumber
1
Tampaknya tidak benar-benar menambahkan sesuatu yang baru dibandingkan dengan jawaban oleh David Ackerman, chetan dan Tanmay kumar shaw, bukan?
Ole VV
1

Metode untuk membandingkan 2 tanggal (util.date atau 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
sumber
0

coba dengan ini

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
sumber
-1

Saya pikir cara terbaik untuk mengkonversi adalah:

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

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

Jika Anda ingin memasukkan dtvariabel ke tabel SQL yang dapat Anda lakukan:

insert into table (expireAt) values ('"+dt+"');
pengguna6043502
sumber
1
Tampaknya ini pada dasarnya sama dengan jawaban yang diposting setahun sebelumnya.
Bernhard Barker
-3

saya menggunakan kode berikut, silakan coba

DateFormat fm= new SimpleDateFormatter();

tentukan format tanggal yang Anda inginkan misalnya "DD-MM_YYYY"atau 'YYYY-mm-dd' kemudian gunakan datatype Date java sebagai

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

maka itu akan mengurai tanggal Anda

UmeshA
sumber
-3

Anda dapat menggunakan metode ini untuk mengkonversi tanggal util ke tanggal sql,

DateUtilities.convertUtilDateToSql(java.util.Date)
Emmanuel Angelo.R
sumber
Tidak ada kelas DateUtilities di perpustakaan Java standar (dan saya bahkan tidak dapat menemukan metode ini di mana pun sama sekali dari pencarian Google cepat). Jika ini dari perpustakaan tertentu, Anda mungkin ingin mengatakan sebanyak mungkin dan menyertakan tautan ke dokumen.
Bernhard Barker
-4

Saya mencoba pengkodean berikut yang berfungsi dengan baik.

java.util.Date utilDate = new java.util.Date ();
java.sql.Date sqlDate = java.sql.Date baru (utilDate);

PONRAJ
sumber
-8

Jika Anda menggunakan Mysql kolom tanggal dapat dilewatkan representasi String dari tanggal ini

jadi saya menggunakan DateFormatter Class untuk memformatnya dan kemudian mengaturnya sebagai String dalam pernyataan sql atau pernyataan yang disiapkan

di sini adalah ilustrasi kode:

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

String date = convertUtilDateToSqlDate (otherTransaction.getTransDate ());

// lalu sampaikan tanggal ini dalam pernyataan sql Anda

Benjamin Ndugga
sumber
14
Selamat datang di stackoverflow, saya punya beberapa komentar untuk jawaban Anda. Pertanyaannya adalah "bagaimana mengkonversi java.util.Date ke java.sql.Date". Kode yang Anda tempelkan memformat java.util.Date sebagai yyyy-MM-dd. Ini sebenarnya penggunaan terbatas dalam konteks ini karena Anda harus melewati java.sql.Date langsung ke driver jdbc alih-alih melakukannya sebagai string.
jontro