วิธีการแปลง TimeStamp เป็น Date ใน Java?


106

ฉันจะแปลง 'timeStamp' เป็นdateหลังจากได้รับการนับใน java ได้อย่างไร

รหัสปัจจุบันของฉันมีดังนี้:

public class GetCurrentDateTime {

    public int data() {
        int count = 0;
        java.sql.Timestamp timeStamp = new Timestamp(System.currentTimeMillis());
        java.sql.Date date = new java.sql.Date(timeStamp.getTime()); 
        System.out.println(date);
        //count++;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/pro", "root", "");

            PreparedStatement statement = con.prepareStatement("select * from orders where status='Q' AND date=CURDATE()");
            ResultSet result = statement.executeQuery();
            while (result.next()) {
                // Do something with the row returned.
                count++; //if the first col is a count.
            }
        } catch (Exception exc) {
            System.out.println(exc.getMessage());
        }

        return count;
    }
}

นี่คือฐานข้อมูลของฉัน: ป้อนคำอธิบายภาพที่นี่

ที่นี่ผลลัพธ์ที่ฉันได้คือ 2012-08-07 0 แต่แบบสอบถามที่เทียบเท่าส่งคืน 3 ทำไมฉันถึงได้ 0?



คุณสามารถแสดงตัวอย่างของข้อมูลตารางได้หรือไม่?
oldrinb

วันที่ (1344255451,1344255537,1344312502) และสถานะมี (Q, Q, Q)
กฤษณะเวนี


ชื่อของคำถามนี้เป็นปลาชนิดหนึ่งสีแดง ปัญหาที่แท้จริงคือการใช้PreparedStatementไวยากรณ์ที่ไม่ถูกต้องอย่างไม่เหมาะสม คุณไม่สามารถฝังตัวแปร Java ในข้อความของสตริง SQL ของคุณ ให้ฝัง?ในสตริง SQL แทนจากนั้นเรียกใช้setเมธอดเพื่อส่งผ่านค่าไปยัง PreparedStatement ดูที่ถูกต้องคำตอบโดย Sujayและคำตอบโดย tenorsax
Basil Bourque

คำตอบ:


189

เพียงสร้างDateวัตถุใหม่โดยใช้getTime()ค่าของตราประทับเป็นพารามิเตอร์

นี่คือตัวอย่าง (ฉันใช้ตัวอย่างการประทับเวลาของเวลาปัจจุบัน):

Timestamp stamp = new Timestamp(System.currentTimeMillis());
Date date = new Date(stamp.getTime());
System.out.println(date);

@ vs06 อะไรทำให้คุณคิดว่าเลิกใช้แล้ว? เอกสาร java 7 และ 8 ล่าสุดบอกเป็นอย่างอื่น ( docs.oracle.com/javase/7/docs/api/java/util/Date.html#getTime ()และdocs.oracle.com/javase/8/docs/api /java/util/Date.html#getTime-- )
Alex Coleman

4
สิ่งนี้จะให้ผลลัพธ์ที่ไม่ถูกต้องหากเขตเวลา Timestamp และเขตเวลา JVM แตกต่างกัน
Robert Mugattarov

จะจัดรูปแบบเป็น 14.03.2014 ได้อย่างไร?
shurrok

6
ฉันเกลียดเมื่อ ppl ใช้ไลบรารีในคำตอบของพวกเขาและคาดหวังให้ทุกคนรู้วิธีนำเข้า: /
Sodj

38
// timestamp to Date
long timestamp = 5607059900000; //Example -> in ms
Date d = new Date(timestamp );

// Date to timestamp
long timestamp = d.getTime();

//If you want the current timestamp :
Calendar c = Calendar.getInstance();
long timestamp = c.getTimeInMillis();

ทำไมคุณคูณมันด้วย 1,000?
Sharpless512

3
เนื่องจากการเริ่มต้นของวันที่เป็นมิลลิวินาทีและการประทับเวลาเป็นวินาที! คิดเหมือนกันสำหรับการเปลี่ยนแปลงอื่น ๆ ทั้งหมด! ดี ?
VincentLamoute


7

ฉันมองหาสิ่งนี้มานานแล้วปรากฎว่าตัวแปลง Eposhทำได้อย่างง่ายดาย:

long epoch = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970 01:00:00").getTime() / 1000;

หรือตรงกันข้าม:

String date = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new java.util.Date (epoch*1000));

6

tl; dr

LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
    .atStartOfDay( ZoneId.of( "Africa/Tunis" ) )
    .toEpochSecond()

LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
    .plusDays( 1 )
    .atStartOfDay( ZoneId.of( "Africa/Tunis" ) )
    .toEpochSecond()

"SELECT * FROM orders WHERE placed >= ? AND placed < ? ; "

myPreparedStatement.setObject( 1 , start )
myPreparedStatement.setObject( 2 , stop )

java.time

คุณกำลังใช้คลาสวันที่และเวลาเก่าที่มีปัญหาซึ่งตอนนี้เป็นแบบดั้งเดิมแทนที่ด้วยคลาสjava.time ที่ทันสมัย

เห็นได้ชัดว่าคุณกำลังจัดเก็บช่วงเวลาหนึ่งในฐานข้อมูลของคุณในคอลัมน์ประเภทจำนวนเต็ม นั่นเป็นเรื่องโชคร้าย คุณควรใช้คอลัมน์ประเภทเช่น SQL-standard TIMESTAMP WITH TIME ZONEแทน แต่สำหรับคำตอบนี้เราจะดำเนินการกับสิ่งที่เรามี

หากบันทึกของคุณแสดงช่วงเวลาที่มีความละเอียดเป็นมิลลิวินาทีและคุณต้องการบันทึกทั้งหมดตลอดทั้งวันเราก็ต้องมีช่วงเวลา เราต้องมีช่วงเวลาเริ่มต้นและช่วงเวลาหยุด ข้อความค้นหาของคุณมีเพียงเกณฑ์วันที่และเวลาเดียวที่ควรมีคู่

LocalDateชั้นหมายถึงค่าวันเท่านั้นโดยไม่ต้องเวลาของวันและไม่มีโซนเวลา

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

หากไม่ได้ระบุเขตเวลา JVM จะใช้โซนเวลาเริ่มต้นปัจจุบันโดยปริยาย ค่าเริ่มต้นนั้นอาจเปลี่ยนแปลงได้ตลอดเวลาดังนั้นผลลัพธ์ของคุณอาจแตกต่างกันไป ควรระบุเขตเวลาที่คุณต้องการ / ที่คาดไว้อย่างชัดเจนเป็นอาร์กิวเมนต์

ระบุชื่อโซนเวลาที่เหมาะสมในรูปแบบของcontinent/regionเช่นAmerica/Montreal, หรือAfrica/Casablanca Pacific/Aucklandอย่าใช้อักษรย่อ 3-4 ตัวเช่นESTหรือISTเนื่องจากไม่ใช่เขตเวลาจริงไม่เป็นมาตรฐานและไม่ซ้ำกัน (!)

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

หากคุณต้องการใช้เขตเวลาเริ่มต้นปัจจุบันของ JVM ให้ถามและส่งผ่านเป็นอาร์กิวเมนต์ หากไม่ระบุค่าเริ่มต้นปัจจุบันของ JVM จะถูกนำไปใช้โดยปริยาย ดีกว่าที่จะชัดเจนเนื่องจากค่าเริ่มต้นอาจเปลี่ยนแปลงได้ตลอดเวลาระหว่างรันไทม์โดยใช้รหัสใด ๆ ในเธรดของแอปใด ๆ ภายใน JVM

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

หรือระบุวันที่ คุณสามารถกำหนดเดือนด้วยตัวเลขโดยมีเลข 1-12 สำหรับเดือนมกราคม - ธันวาคม

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

หรือที่ดีกว่าคือใช้อMonthอบเจ็กต์ enum ที่กำหนดไว้ล่วงหน้าหนึ่งรายการสำหรับแต่ละเดือนของปี เคล็ดลับ: ใช้เหล่านี้Monthวัตถุทั่ว codebase ของคุณแทนที่จะเป็นจำนวนเต็มเพียงที่จะทำให้รหัสของคุณเองมากขึ้นการจัดเก็บเอกสารให้ตรวจสอบค่าที่ถูกต้องและให้ประเภทความปลอดภัย

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

เมื่อLocalDateอยู่ในมือเราต้องเปลี่ยนสิ่งนั้นให้เป็นช่วงเวลาหนึ่งจุดเริ่มต้นและจุดหยุดของวัน อย่าถือว่าวันเริ่มเวลา 00:00:00 น. ตามเวลาของวัน เนื่องจากความผิดปกติเช่นเวลาออมแสง (DST) วันอาจเริ่มต้นในเวลาอื่นเช่น 01:00:00 น. ดังนั้นให้ java.time กำหนดช่วงเวลาแรกของวัน เราผ่านการZoneIdโต้แย้งLocalDate::atStartOfDayเพื่อค้นหาความผิดปกติดังกล่าว ผลลัพธ์คือZonedDateTime.

ZonedDateTime zdtStart = ld.atStartOfDay( z ) ;

โดยทั่วไปวิธีที่ดีที่สุดที่จะกำหนดช่วงเวลาที่เป็นวิธีที่ครึ่งเปิดที่จุดเริ่มต้นคือรวมในขณะที่ตอนจบเป็นพิเศษ ดังนั้นวันเริ่มต้นด้วยช่วงเวลาแรกและดำเนินไปถึง แต่ไม่รวมถึงช่วงเวลาแรกของวันถัดไป

ZonedDateTime zdtStop = ld.plusDays( 1 ).atStartOfDay( z ) ;  // Determine the following date, and ask for the first moment of that day.

แบบสอบถามของเราตลอดทั้งวันไม่สามารถใช้คำสั่ง SQL BETWEENได้ คำสั่งนั้นคือ Fully-Closed ( []) (รวมทั้งจุดเริ่มต้นและจุดสิ้นสุด) โดยที่เราต้องการ Half-Open ( [)) เราใช้คู่ของเกณฑ์>=และ<.

คอลัมน์ของคุณตั้งชื่อไม่ดี หลีกเลี่ยงพันคำที่สงวนไว้โดยฐานข้อมูลต่างๆ มาใช้placedในตัวอย่างนี้

รหัสของคุณควรใช้?ตัวยึดตำแหน่งเพื่อระบุช่วงเวลาของเรา

String sql = "SELECT * FROM orders WHERE placed >= ? AND placed < ? ; " ;

แต่เรามีZonedDateTimeวัตถุอยู่ในมือในขณะที่ฐานข้อมูลของคุณกำลังจัดเก็บจำนวนเต็มตามที่กล่าวไว้ข้างต้น หากคุณได้กำหนดคอลัมน์ของคุณอย่างถูกต้องเราก็สามารถผ่านZonedDateTimeวัตถุใด ๆ ไดรเวอร์ JDBC สนับสนุน JDBC 4.2 หรือในภายหลัง

แต่เราจำเป็นต้องได้รับการนับจากยุคในเวลาไม่กี่วินาทีแทน ฉันจะถือว่าวันที่อ้างอิงของคุณเป็นช่วงเวลาแรกของปี 1970 ใน UTC โปรดระวังการสูญหายของข้อมูลเนื่องจากZonedDateTimeคลาสนี้มีความละเอียดระดับนาโนวินาที เศษส่วนของวินาทีจะถูกตัดทอนในบรรทัดต่อไปนี้

long start = zdtStart().toEpochSecond() ;  // Transform to a count of whole seconds since 1970-01-01T00:00:00Z.
long stop = zdtStop().toEpochSecond() ; 

ตอนนี้เราพร้อมที่จะส่งต่อจำนวนเต็มเหล่านั้นไปยังโค้ด SQL ของเราที่กำหนดไว้ข้างต้น

PreparedStatement ps = con.prepareStatement( sql );
ps.setObject( 1 , start ) ;
ps.setObject( 2 , stop ) ;
ResultSet rs = ps.executeQuery();

เมื่อคุณดึงค่าจำนวนเต็มของคุณจากค่าResultSetนี้คุณสามารถแปลงเป็นInstantอ็อบเจกต์ (ใน UTC เสมอ) หรือเป็นZonedDateTimeอ็อบเจกต์ (ด้วยเขตเวลาที่กำหนด)

Instant instant = rs.getObject(  , Instant.class ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

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

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

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

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

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

  • Java SE 8 , Java SE 9และใหม่กว่า
    • ในตัว.
    • ส่วนหนึ่งของ Java API มาตรฐานพร้อมการใช้งานแบบรวม
    • Java 9 เพิ่มคุณสมบัติและการแก้ไขเล็กน้อย
  • Java SE 6และ Java SE 7
    • มากของการทำงาน java.time จะกลับรังเพลิง Java 6 และ 7 ในThreeTen-ย้ายกลับ
  • Android
    • การติดตั้งบันเดิล Android เวอร์ชันที่ใหม่กว่าของคลาส java.time
    • สำหรับก่อนหน้านี้ของ Android ที่ThreeTenABPโครงการปรับThreeTen-ย้ายกลับ (ดังกล่าวข้างต้น) ดูวิธีใช้ ThreeTenABP … .

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


4

ก่อนอื่นคุณไม่ได้ใช้ประโยชน์จากการใช้ไฟล์PreparedStatement. ก่อนอื่นฉันขอแนะนำให้คุณแก้ไขของคุณPreparedStatementดังนี้:

PreparedStatement statement = con.prepareStatement("select * from orders where status=? AND date=?")

จากนั้นคุณสามารถใช้statement.setXX(param_index, param_value)เพื่อตั้งค่าตามลำดับ สำหรับการแปลงtimestampเป็นดู javadocs ต่อไปนี้:

PreparedStatement.setTimeStamp ()
Timestamp

หวังว่านี่จะช่วยได้!


4

ใน Android มันง่ายมากเพียงแค่ใช้คลาส Calender เพื่อรับ currentTimeMillis

Timestamp stamp = new Timestamp(Calendar.getInstance().getTimeInMillis());
Date date = new Date(stamp.getTime());
Log.d("Current date Time is   "  +date.toString());

ใน Java ให้ใช้ System.currentTimeMillis () เพื่อรับการประทับเวลาปัจจุบัน


3

ไม่แน่ใจว่าคุณกำลังพยายามเลือกอะไรในข้อความค้นหา แต่โปรดทราบว่าการUNIX_TIMESTAMP()ไม่มีข้อโต้แย้งจะส่งคืนเวลาในขณะนี้ คุณควรระบุเวลาที่ถูกต้องเป็นอาร์กิวเมนต์หรือเปลี่ยนเงื่อนไข

แก้ไข:

นี่คือตัวอย่างของข้อความค้นหาที่มีขอบเขตเวลาตามคำถาม:

PreparedStatement statement = con
        .prepareStatement("select * from orders where status='Q' AND date > ?");
Date date = new SimpleDateFormat("dd/MM/yyyy").parse("01/01/2000");
statement.setDate(1, new java.sql.Date(date.getTime()));

แก้ไข: คอลัมน์การประทับเวลา

ในกรณีของการใช้การประทับเวลาjava.sql.TimestampและPreparedStatement.setTimestamp ()เช่น:

PreparedStatement statement = con
        .prepareStatement("select * from orders where status='Q' AND date > ?");
Date date = new SimpleDateFormat("dd/MM/yyyy").parse("01/01/2000");
Timestamp timestamp = new Timestamp(date.getTime());
statement.setTimestamp(1, timestamp);

ตอนนี้เงื่อนไขของฉันคือเลือก * จาก xcart_orders โดยที่ status = 'Q' AND date = CURDATE () ตอนนี้แสดงเป็นศูนย์เท่านั้น
กฤษณะเวนิ

@krishnaveni คุณพยายามเลือกบันทึกอะไร
tenorsax

วันที่ (11111111,123456767,122333344) และสถานะ = (Q, Q, Q) .. ทั้งหมดถูกบันทึกไว้ในฐานข้อมูลของฉันตอนนี้ฉันต้องการตรวจสอบแบบสอบถามและรับค่าการนับและแสดงบนคอนโซลของฉัน (กล่าวคือ) จำนวนเท่าใด ข้อมูลจะถูกจับคู่หลังจากส่งคืนค่าการนับ
กฤษณะเวนิ

@krishnaveni หากคุณต้องการให้ชุดผลลัพธ์ถูกผูกมัดด้วยวันที่ที่กำหนดให้ใช้วันที่นั้นในแบบสอบถามหรือลบเงื่อนไขวันที่
tenorsax

ในรหัสของฉันทำงานได้สำเร็จเมื่อวันที่อยู่ในรูปแบบ yyyy-mm-dd ที่บันทึกไว้ในฐานข้อมูลของฉัน แต่ตอนนี้วันที่ของฉันถูกบันทึกในการประทับเวลาในรูปแบบ 1343469690 นี้ รับค่านับเป็นอย่างไรฉันจะเขียนโค้ดที่นี่ได้อย่างไร
กฤษณะเวนิ

3

new Date(timestamp.getTime())ควรจะทำงาน แต่แฟนซีใหม่ Java 8 วิธี (ซึ่งอาจจะสง่างามมากขึ้นและปลอดภัยประเภทมากขึ้นรวมทั้งช่วยทำให้คุณใช้เวลาเรียนใหม่) Date.from(timestamp.toInstant())คือการโทร

(อย่าพึ่งพาความจริงที่ว่าTimestampตัวเองเป็นตัวอย่างDateดูคำอธิบายในความคิดเห็นของคำตอบอื่น )



3

ฉันรู้สึกว่าจำเป็นต้องตอบกลับเนื่องจากคำตอบอื่น ๆ ดูเหมือนจะไม่เชื่อเรื่องพระเจ้าตามเขตเวลาซึ่งแอปพลิเคชันในโลกแห่งความเป็นจริงไม่สามารถจ่ายได้ เพื่อให้การแปลงเวลาประทับเป็นวันที่ถูกต้องเมื่อการประทับเวลาและ JVM ใช้เขตเวลาที่แตกต่างกันคุณสามารถใช้ LocalDateTime ของ Joda Time (หรือ LocalDateTime ใน Java8) ได้ดังนี้:

Timestamp timestamp = resultSet.getTimestamp("time_column");
LocalDateTime localDateTime = new LocalDateTime(timestamp);
Date trueDate = localDateTime.toDate(DateTimeZone.UTC.toTimeZone());

ตัวอย่างด้านล่างนี้ถือว่าการประทับเวลาเป็น UTC (ตามปกติในกรณีของฐานข้อมูล) ในกรณีที่การประทับเวลาของคุณอยู่ในเขตเวลาที่ต่างกันให้เปลี่ยนพารามิเตอร์เขตเวลาของtoDateคำสั่ง


3

ลองใช้รหัส java นี้:

Timestamp stamp = new Timestamp(System.currentTimeMillis());
Date date = new Date(stamp.getTime());
DateFormat f = new SimpleDateFormat("yyyy-MM-dd");
DateFormat f1 = new SimpleDateFormat("yyyy/MM/dd");
String d = f.format(date);
String d1 = f1.format(date);
System.out.println(d);
System.out.println(d1);


0

คุณสามารถใช้วิธีนี้เพื่อรับวันที่จาก Timestamp และ Time-zone ของพื้นที่ใดพื้นที่หนึ่ง

public String getDayOfTimestamp(long yourLinuxTimestamp, String timeZone) {
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(yourLinuxTimestamp * 1000);
    cal.setTimeZone(TimeZone.getTimeZone(timeZone));
    Date date = cal.getTime();
}

-1
String timestamp="";
Date temp=null;
try {
    temp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(getDateCurrentTimeZone(Long.parseLong(timestamp)));
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
int dayMonth=temp.getDate();
int dayWeek=temp.getDay();
int hour=temp.getHours();
int minute=temp.getMinutes();
int month=temp.getMonth()+1;
int year=temp.getYear()+1900;

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