Java Timestamp - ฉันจะสร้าง Timestamp ในวันที่ 23/09/2007 ได้อย่างไร


คำตอบ:


157

โดยผมคิดว่าคุณหมายถึงTimestamp java.sql.Timestampคุณจะสังเกตเห็นว่าคลาสนี้มีตัวสร้างที่ยอมรับการlongโต้แย้ง คุณสามารถแยกวิเคราะห์โดยใช้DateFormatคลาส:

DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = dateFormat.parse("23/09/2007");
long time = date.getTime();
new Timestamp(time);

1
รูปแบบวันที่ ISO ปกติคือ yyyy-MM-dd มิฉะนั้นจะดีมาก!
vidstige

1
การประทับเวลาใหม่ (เวลา); ให้ข้อผิดพลาดที่ไม่มีตัวสร้างเช่นนี้ซึ่งใช้เวลาค่ายาว :(
Bhanu Sharma

1
@Bhanu เอกสารแสดงสิ่งนี้ใช้เวลานานและดูเหมือนจะทำงานได้อย่างถูกต้อง: docs.oracle.com/javase/7/docs/api/java/sql/…
Hazok

FYI, ลำบากชะมัดเก่าชั้นเรียนวันที่เวลาเช่นjava.util.Date, java.util.Calendarและjava.text.SimpleDateFormatตอนนี้มรดกแทนที่โดยjava.timeชั้นเรียนที่สร้างขึ้นใน Java 8 และต่อมา ดูการสอนโดยออราเคิล
Basil Bourque

123

อะไรประมาณนี้

java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");

1
Timestamp timestamp = Timestamp.valueOf ("2007-09-23 10: 10: 10.0"); กำลังแสดงค่าวิธีการไม่ได้กำหนดไว้สำหรับประเภทการประทับเวลาใน jDK 7
Ashish Ratan

การประทับเวลาใหม่ (เวลา); ให้ข้อผิดพลาดที่ไม่มีตัวสร้างเช่นนี้ซึ่งใช้ค่าสตริง :(
Bhanu Sharma

@Bhanu ตัวสร้างใช้เวลายูนิกซ์เป็นมิลลิวินาที ใช้ค่าวิธีการคงที่ถ้าคุณต้องการรับการประทับเวลาจากสตริง
Hazok

4
ดูเหมือนจะเป็นคำตอบที่ดีที่สุดสำหรับคำถามนี้
Hazok

1
คำตอบที่ดีที่สุดคือ Date ซึ่งเลิกใช้แล้วเป็นการใช้งานที่ไม่ดี คำตอบนี้ดีกว่า ขอบคุณ
Alberici

18

คุณหมายถึงอะไรประทับเวลา? หากคุณหมายถึงมิลลิวินาทีนับตั้งแต่ยุค Unix:

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

หากคุณต้องการวัตถุ java.sql.Timestamp จริง:

Timestamp ts = new Timestamp(millis);

2
ผิดและจะไม่รวบรวม! ข้อผิดพลาดในการคอมไพล์: 09 เป็นเลขฐานแปด แต่ 9 อยู่นอกช่วงสำหรับฐานแปด ข้อผิดพลาดลอจิก: เดือนเป็น 0-based คุณจะได้รับ 23 ตุลาคม 2550
user85421

ฉันไม่สามารถรับข้อผิดพลาดทางตรรกะหากไม่ได้รวบรวม :) อย่างจริงจังจับดีคาร์ลอส ฐานแปดที่ฉันจับได้ก่อนหน้านี้ แต่วางผิดอยู่ดี :(
Matthew Flaschen

อันที่จริงแล้วตัวสร้างการประทับเวลาถูกตัดทอน แต่คุณสามารถใช้วิธี Timestamp.valueOf ()
Shiva Komuravelly

@ShivaKomuravelly ไม่ใช่ตัวสร้างการประทับเวลาทั้งหมดที่เลิกใช้งานและอย่างน้อยที่สุดก็ไม่ใช้เวลานานเป็นมิลลิวินาทีตัวสร้างที่ใช้วันที่เนื่องจากอาร์กิวเมนต์เลิกใช้งาน
ไม่มีชื่อ

และมีค่าคงที่สำหรับสิ่งนั้น (แทนที่จะเป็นเดือน = 9):Calendar.SEPTEMBER
Guillaume Husta

12

tl; dr

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

java.time

มาอัปเดตหน้านี้โดยแสดงโค้ดโดยใช้java.timeกรอบสร้างใน Java 8 ขึ้นไป

คลาสใหม่เหล่านี้ได้รับแรงบันดาลใจจากJoda-Timeซึ่งกำหนดโดยJSR 310และขยายโดยThreeTen-Extraโครงการ พวกเขาเข้ามาแทนที่คลาสวันเวลาเก่าที่มีปัญหาซึ่งมาพร้อมกับ Java เวอร์ชันแรก ๆ

ใน java.time Instantคือช่วงเวลาหนึ่งบนไทม์ไลน์ใน UTC A ZonedDateTimeคือการปรับเปลี่ยนทันทีเป็นเขตเวลา ( ZoneId)

เขตเวลาเป็นสิ่งสำคัญสำหรับที่นี่ วันของการSeptember 23, 2007ไม่สามารถได้รับการแปลถึงช่วงเวลาในระยะเวลาโดยไม่ต้องใช้โซนเวลา พิจารณาว่าวันใหม่เริ่มต้นในปารีสเร็วกว่าที่มอนทรีออลซึ่งยังคงเป็น“ เมื่อวาน”

นอกจากนี้ java.sql.Timestamp แสดงทั้งวันที่และเวลาของวัน ดังนั้นเราต้องฉีดเวลาของวันเพื่อให้ตรงกับวันที่ เราถือว่าคุณต้องการช่วงเวลาแรกของวันเป็นช่วงเวลาของวัน โปรดทราบว่านี่ไม่ใช่เวลาเสมอไป00:00:00.0เนื่องจากเวลาออมแสงและอาจเป็นความผิดปกติอื่น ๆ

โปรดทราบว่าไม่เหมือนกับคลาส java.util.Date แบบเก่าและต่างจาก Joda-Time ประเภท java.time มีความละเอียดของนาโนวินาทีแทนที่จะเป็นมิลลิวินาที ตรงกับความละเอียดของ java.sql.Timestamp

โปรดสังเกตว่า java.sql.Timestamp มีนิสัยที่น่ารังเกียจในการใช้เขตเวลาเริ่มต้นปัจจุบันของ JVM กับค่าวันที่ - เวลาโดยปริยายเมื่อสร้างการแสดงสตริงด้วยtoStringวิธีการ คุณจะเห็นAmerica/Los_Angelesเขตเวลาของฉันที่ใช้ ในทางตรงกันข้ามคลาส java.time มีเหตุผลมากกว่าโดยใช้รูปแบบ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 ) ;

ถ่ายโอนไปยังคอนโซล

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

เมื่อเรียกใช้.

d: 2007-09-23 = zdt: 2007-09-23T00: 00-04: 00 [อเมริกา / มอนทรีออล] = ทันที: 2007-09-23T04: 00: 00Z = ts: 2007-09-22 21:00: 00.0

อย่างไรก็ตามใน JDBC 4.2 คุณสามารถใช้ประเภท java.time ได้โดยตรง ไม่จำเป็นต้องjava.sql.Timestamp.

  • PreparedStatement.setObject
  • ResultSet.getObject

เกี่ยวกับjava.time

java.timeกรอบถูกสร้างขึ้นใน Java 8 และต่อมา ชั้นเรียนเหล่านี้แย่งลำบากเก่ามรดกเรียนวันที่เวลาเช่นjava.util.Date, และCalendarSimpleDateFormat

โครงการJoda-Timeขณะนี้อยู่ในโหมดการบำรุงรักษาแนะนำให้ย้ายไปที่คลาสjava.time

ต้องการเรียนรู้เพิ่มเติมโปรดดูที่ออราเคิลกวดวิชา และค้นหา Stack Overflow สำหรับตัวอย่างและคำอธิบายมากมาย สเปกJSR 310

คุณสามารถแลกเปลี่ยนวัตถุjava.timeโดยตรงกับฐานข้อมูลของคุณ ใช้ไดรเวอร์ JDBC ที่สอดคล้องกับJDBC 4.2หรือใหม่กว่า ไม่จำเป็นต้องมีสตริงไม่จำเป็นต้องมีjava.sql.*คลาส

จะหาคลาส java.time ได้ที่ไหน?

  • Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11และใหม่กว่า - เป็นส่วนหนึ่งของ Java API มาตรฐานพร้อมการใช้งานแบบรวม
    • Java 9 เพิ่มคุณสมบัติและการแก้ไขเล็กน้อย
  • Java SE 6และ Java SE 7
    • ส่วนใหญ่ของjava.timeการทำงานจะกลับรังเพลิง Java 6 และ 7 ในThreeTen-ย้ายกลับ
  • Android

โครงการThreeTen-Extraขยาย java.time ด้วยคลาสเพิ่มเติม โปรเจ็กต์นี้เป็นพื้นที่พิสูจน์สำหรับการเพิ่ม java.time ในอนาคต คุณอาจพบว่าการเรียนที่มีประโยชน์บางอย่างที่นี่เช่นInterval, YearWeek, YearQuarterและอื่น ๆ อีกมากมาย


3
ฉันสงสัยว่าฉันจะรับ OP หรือ mods เพื่อทำเครื่องหมายคำตอบของคุณว่าถูกต้องได้อย่างไร คำตอบที่ยอมรับนั้นล้าสมัยมาก
sttaq

ดีมากยกเว้นการพิมพ์ผิด asStartOfDay () ควรอยู่ที่StartOfDay ()
Tullochgorum

@Tullochgorum คง. ขอบคุณ. FYI ใน Stack Overflow คุณสามารถแก้ไขได้ด้วยตัวเองหากคุณมีความโน้มเอียงมาก
Basil Bourque

5

คุณสามารถทำสิ่งต่อไปนี้ได้:

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

2
ผิด: ลอง System.out.println ของผลลัพธ์! คุณจะได้รับสิ่งต่างๆเช่น: "2009-10-23 15: 26: 56.171" เดือนเป็น 0 ตามดังนั้น 9 คือตุลาคม!
user85421

ฉันรู้ว่าค่าคงที่ค่าหนึ่งเป็นศูนย์ขอบคุณ อัปเดตโพสต์แล้ว
Alex

1
โอ้ฉันใส่ 'ยังไม่ทดลอง' :)
Alex

4

ตามAPIตัวสร้างที่ยอมรับปีเดือนและอื่น ๆ จะเลิกใช้งาน คุณควรใช้ Constructor ซึ่งยอมรับไฟล์. คุณสามารถใช้การใช้งานปฏิทินเพื่อสร้างวันที่ที่คุณต้องการและเข้าถึงการแสดงเวลาเป็นเวลานานตัวอย่างเช่นด้วยเมธอดgetTimeInMillis


1

เพื่อความสมบูรณ์นอกจากนี้โซลูชันที่มีJoda-Timeเวอร์ชัน 2.5 และDateTimeระดับ:

new Timestamp(new DateTime(2007, 9, 23, 0, 0, DateTimeZone.forID( "America/Montreal" )).getMillis())

1
คำตอบที่ดี แต่คุณพลาดอย่างใดอย่างหนึ่งที่สำคัญชิ้น: โซนเวลา หากคุณเว้นเขตเวลาเขตเวลาเริ่มต้นปัจจุบันของ JVM จะใช้กับDateTimeออบเจ็กต์ นั่นหมายความว่าผลลัพธ์ของคุณจะแตกต่างกันไปตามคอมพิวเตอร์ต่างๆหรือการกำหนดค่าโฮสต์ OS หรือการตั้งค่า JVM เพื่อให้ได้ผลลัพธ์ที่คาดเดาได้ให้ส่งเขตเวลาไปยังตัวDateTimeสร้างนั้น เลือกชื่อเขตเวลาที่เหมาะสมสำหรับความตั้งใจของคุณ ตัวอย่างเช่นDateTimeZone.forID( "America/Montreal" )หรือDateTimeZone.UTC.
Basil Bourque

รหัสนั้นอาจเป็น briefer ไม่จำเป็นต้องแปลง java.util.Date ที่จะได้รับและผ่านมิลลิวินาที-since- ยุค เพียงแค่ถามDateTimeวัตถุเป็นมิลลิวินาทีตั้งแต่ยุค แทนที่.toDate().getTime()ด้วย.getMillis().
Basil Bourque

@BasilBourque ขึ้นอยู่กับสถานการณ์คุณอาจต้องการออกจากเขตเวลาเพื่อให้ได้ผลลัพธ์ที่คาดเดาได้ "ในเขตเวลาปัจจุบันของคุณ" อาจเป็นผลลัพธ์ที่สมเหตุสมผลและคาดเดาได้อย่างสมบูรณ์แบบ ทำไมต้องฮาร์ดโค้ดเขตเวลาหรือขอให้คุณตั้งค่าเขตเวลาด้วยตนเองเมื่อคอมพิวเตอร์ของพวกเขาตั้งเขตเวลาไว้แล้ว แน่นอนว่าฉันจะค่อนข้างแปลกใจถ้าแอปพลิเคชันบนคอมพิวเตอร์ของฉันเริ่มแสดงวันที่ที่ปรับเป็นเขตเวลาอเมริกา / มอนทรีออล
dan carter

@dancarter การละเว้นเขตเวลาที่ไม่บังคับทำให้เกิดความสับสน การละเว้นทำให้เกิดความคลุมเครือของ (a) โปรแกรมเมอร์ตั้งใจที่จะใช้ค่าเริ่มต้นโดยปริยายหรือ (b) โปรแกรมเมอร์ไม่ได้พิจารณาปัญหาเกี่ยวกับเขตเวลา (ซึ่งเป็นเรื่องธรรมดาเกินไป) หากคุณต้องการใช้เขตเวลาเริ่มต้นปัจจุบันของ JVM ให้พูดอย่างชัดเจนโดยการเรียกDateTimeZone.getDefault()และส่งผลลัพธ์เป็นอาร์กิวเมนต์ที่ไม่บังคับ (อย่างไรก็ตามสำหรับLocale.getDefault()ปัญหาเดียวกันกับความคลุมเครือของข้อโต้แย้งที่เป็นทางเลือก)
Basil Bourque

-1

คำตอบทั่วไปมากขึ้นจะนำเข้าjava.util.Dateแล้วเมื่อคุณจำเป็นต้องตั้งค่าเท่ากับวันที่ปัจจุบันเพียงแค่ตั้งค่าเท่ากับtimestampnew Date()


เพราะ ** Date ("สตริง"); ** เลิกใช้แล้ว
Ashish Ratan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.