Làm thế nào để chuyển đổi TimeStamp sang Date trong Java?


105

Làm cách nào để chuyển đổi 'timeStamp' thành datesau khi tôi nhận được số lượng trong java?

Mã hiện tại của tôi như sau:

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

Đây là cơ sở dữ liệu của tôi: nhập mô tả hình ảnh ở đây

Ở đây kết quả đầu ra tôi nhận được là 2012-08-07 0, nhưng truy vấn tương đương trả về 3. Tại sao tôi nhận được 0?



Bạn có thể cho chúng tôi xem ví dụ về dữ liệu bảng trông như thế nào không?
oldrinb

ngày (1344255451,1344255537,1344312502) và trạng thái có (Q, Q, Q)
Krishna Veni


Tiêu đề của Câu hỏi này là một con cá trích đỏ . Vấn đề thực sự là việc sử dụng không đúng một PreparedStatementvới cú pháp không chính xác. Bạn không thể nhúng các biến Java vào văn bản của chuỗi SQL của mình. Thay vào đó, hãy nhúng ?vào chuỗi SQL, sau đó gọi các setphương thức để chuyển các giá trị cho PreparedStatement. Xem Câu trả lời đúng của SujayCâu trả lời của tenorsax .
Basil Bourque

Câu trả lời:


188

Chỉ cần tạo một Dateđối tượng mới với getTime()giá trị của tem làm tham số.

Đây là một ví dụ (tôi sử dụng một dấu thời gian mẫu của thời gian hiện tại):

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

@ vs06 Điều gì khiến bạn nghĩ rằng nó không còn được dùng nữa? Các tài liệu java 7 và 8 mới nhất đều nói khác ( 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
Điều này sẽ tạo ra kết quả không chính xác nếu múi giờ Dấu thời gian và múi giờ JVM khác nhau.
Robert Mugattarov

Làm cách nào để lấy định dạng này thành 14.03.2014 chẳng hạn?
shurrok

6
Tôi ghét khi ppl sử dụng thư viện trong câu trả lời của họ và mong muốn tất cả mọi người biết làm thế nào để nhập khẩu: /
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();

Tại sao bạn lại nhân nó với 1000?
Sharpless512

3
Beacause thời gian khởi tạo ngày tính bằng mili giây và dấu thời gian tính bằng giây! Cùng suy nghĩ cho tất cả các chuyển đổi khác! Nó tốt?
VincentLamoute


7

Tôi đã tìm kiếm điều này từ rất lâu, hóa ra công cụ chuyển đổi Eposh thực hiện nó một cách dễ dàng:

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

Hoặc ngược lại:

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

Bạn đang sử dụng các lớp date-time cũ rắc rối mà bây giờ là kế thừa, được thay thế bởi các lớp java.time hiện đại .

Rõ ràng bạn đang lưu trữ một khoảnh khắc trong cơ sở dữ liệu của mình trong một cột của một số kiểu số nguyên. Đó là điều không may. Thay vào đó, bạn nên sử dụng một cột có kiểu như SQL-standard TIMESTAMP WITH TIME ZONE. Nhưng, đối với Câu trả lời này, chúng tôi sẽ làm việc với những gì chúng tôi có.

Nếu bản ghi của bạn đại diện cho những khoảnh khắc với độ phân giải mili giây và bạn muốn tất cả bản ghi cho cả ngày, thì chúng tôi cần một khoảng thời gian. Chúng ta phải có thời điểm bắt đầu và thời điểm dừng lại. Truy vấn của bạn chỉ có một tiêu chí ngày-giờ duy nhất mà nó đáng lẽ phải có một cặp.

Các LocalDatelớp đại diện cho một giá trị ngày tháng chỉ mà không cần thời gian của ngày và không có múi giờ.

Múi giờ rất quan trọng trong việc xác định ngày. Đối với bất kỳ thời điểm nhất định nào, ngày thay đổi trên toàn cầu theo khu vực. Ví dụ: một vài phút sau nửa đêm ở Paris Pháp là một ngày mới trong khi vẫn là “ngày hôm qua” ở Montréal Québec .

Nếu không có múi giờ nào được chỉ định, JVM sẽ áp dụng hoàn toàn múi giờ mặc định hiện tại của nó. Mặc định đó có thể thay đổi bất kỳ lúc nào, vì vậy kết quả của bạn có thể thay đổi. Tốt hơn là chỉ định múi giờ mong muốn / dự kiến ​​của bạn một cách rõ ràng làm đối số.

Chỉ định một tên múi giờ thích hợp trong các định dạng của continent/region, chẳng hạn như America/Montreal, Africa/Casablancahoặc Pacific/Auckland. Không bao giờ sử dụng từ viết tắt 3-4 chữ cái, chẳng hạn như ESThoặc ISTvì chúng không phải là múi giờ thực, không được tiêu chuẩn hóa và thậm chí không phải là duy nhất (!).

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

Nếu bạn muốn sử dụng múi giờ mặc định hiện tại của JVM, hãy yêu cầu múi giờ đó và chuyển làm đối số. Nếu bị bỏ qua, mặc định hiện tại của JVM được áp dụng ngầm. Tốt hơn là rõ ràng, vì mặc định có thể được thay đổi bất kỳ lúc nào trong thời gian chạy bằng bất kỳ mã nào trong bất kỳ chuỗi nào của bất kỳ ứng dụng nào trong JVM.

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

Hoặc chỉ định một ngày. Bạn có thể đặt tháng bằng một số, với việc đánh số lành mạnh từ 1-12 cho tháng 1 đến tháng 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.

Hoặc, tốt hơn, sử dụng các Monthđối tượng enum được xác định trước, một đối tượng cho mỗi tháng trong năm. Mẹo: Sử dụng các Monthđối tượng này trong toàn bộ cơ sở mã của bạn thay vì một số nguyên đơn thuần để làm cho mã của bạn tự ghi lại nhiều hơn, đảm bảo các giá trị hợp lệ và cung cấp an toàn kiểu .

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

Có được LocalDatetrong tay, tiếp theo, chúng ta cần biến nó thành một cặp thời điểm, điểm bắt đầu và điểm dừng trong ngày. Đừng cho rằng ngày bắt đầu lúc 00:00:00 trong ngày. Do những điều bất thường như Giờ tiết kiệm ánh sáng ban ngày (DST), ngày có thể bắt đầu vào một thời điểm khác, chẳng hạn như 01:00:00. Vì vậy, hãy để java.time xác định thời điểm đầu tiên trong ngày. Chúng tôi chuyển một ZoneIdđối số LocalDate::atStartOfDayđể tìm kiếm bất kỳ sự bất thường nào như vậy. Kết quả là a ZonedDateTime.

ZonedDateTime zdtStart = ld.atStartOfDay( z ) ;

Nói chung, cách tiếp cận tốt nhất để xác định khoảng thời gian là cách tiếp cận Nửa mở trong đó phần đầu là bao gồm trong khi phần kết là độc quyền . Vì vậy, một ngày bắt đầu với khoảnh khắc đầu tiên của nó và kéo dài đến, nhưng không bao gồm, khoảnh khắc đầu tiên của ngày hôm sau.

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

Truy vấn của chúng tôi trong cả ngày không thể sử dụng lệnh SQL BETWEEN. Lệnh đó là Full-Closed ( []) (cả phần đầu và phần cuối đều bao gồm) ở nơi chúng ta muốn Half-Open ( [)). Chúng tôi sử dụng một cặp tiêu chí >=<.

Cột của bạn được đặt tên kém. Tránh bất kỳ từ nào trong số hàng nghìn từ được đặt trước bởi các cơ sở dữ liệu khác nhau. Hãy sử dụng placedtrong ví dụ này.

Mã của bạn nên đã sử dụng ?trình giữ chỗ để chỉ định các khoảnh khắc của chúng ta.

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

Nhưng chúng tôi có ZonedDateTimecác đối tượng trong tay, trong khi cơ sở dữ liệu của bạn dường như đang lưu trữ các số nguyên như đã thảo luận ở trên. Nếu bạn đã xác định đúng cột của mình, chúng tôi có thể chỉ cần chuyển các ZonedDateTimeđối tượng bằng bất kỳ trình điều khiển JDBC nào hỗ trợ JDBC 4.2 trở lên.

Nhưng thay vào đó, chúng ta cần đếm từ kỷ nguyên trong cả giây. Tôi sẽ giả sử ngày tham chiếu kỷ nguyên của bạn là thời điểm đầu tiên của năm 1970 theo giờ UTC. Cẩn thận với khả năng mất dữ liệu, vì ZonedDateTimelớp này có khả năng phân giải nano giây. Bất kỳ giây phân số nào sẽ được cắt ngắn trong các dòng sau.

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

Bây giờ chúng ta đã sẵn sàng chuyển các số nguyên đó sang mã SQL của chúng ta được định nghĩa ở trên.

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

Khi bạn truy xuất các giá trị số nguyên của mình từ ResultSet, bạn có thể chuyển đổi thành Instantcác đối tượng (luôn ở UTC) hoặc thành ZonedDateTimecác đối tượng (với múi giờ được chỉ định).

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

Giới thiệu về java.time

Các java.time khung được xây dựng vào Java 8 và sau đó. Những lớp học thay thế cái cũ phiền hà di sản lớp học ngày thời gian như java.util.Date, Calendar, & SimpleDateFormat.

Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang các java.time lớp.

Để tìm hiểu thêm, hãy xem Hướng dẫn Oracle . Và tìm kiếm Stack Overflow để có nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310 .

Lấy các lớp java.time ở đâu?

  • Java SE 8 , Java SE 9 và mới hơn
    • Được xây dựng trong.
    • Một phần của API Java tiêu chuẩn với triển khai theo gói.
    • Java 9 bổ sung một số tính năng nhỏ và các bản sửa lỗi.
  • Java SE 6 Java SE 7
    • Phần lớn chức năng của java.time được chuyển ngược sang Java 6 & 7 trong ThreeTen-Backport .
  • Android
    • Các phiên bản triển khai gói Android mới hơn của các lớp java.time.
    • Đối với Android trước đó, ThreeTenABP dự án thích nghi ThreeTen-backport (nêu trên). Xem Cách sử dụng ThreeTenABP… .

Các ThreeTen-Extra dự án mở rộng java.time với các lớp bổ sung. Dự án này là cơ sở chứng minh cho những bổ sung có thể có trong tương lai cho java.time. Bạn có thể tìm thấy một số các lớp học hữu ích ở đây chẳng hạn như Interval, YearWeek, YearQuarter, và nhiều hơn nữa .


4

Trước hết, bạn không tận dụng được lợi thế của việc sử dụng a PreparedStatement. Trước tiên, tôi đề nghị bạn sửa đổi PreparedStatementnhư sau:

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

Sau đó, bạn có thể sử dụng statement.setXX(param_index, param_value)để đặt các giá trị tương ứng. Để chuyển đổi thànhtimestamp , hãy xem javadocs sau:

Dấu thời gian PreparedStatement.setTimeStamp ()

Hi vọng điêu nay co ich!


4

Trong Android, nó rất đơn giản. Chỉ cần sử dụng lớp Calender để lấy currentTimeMillis.

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

Trong Java chỉ cần Sử dụng System.currentTimeMillis () để lấy dấu thời gian hiện tại


3

Không chắc chắn những gì bạn đang cố gắng chọn trong truy vấn, nhưng hãy nhớ rằng UNIX_TIMESTAMP()không có đối số trả về thời gian ngay bây giờ. Bạn có thể nên cung cấp thời gian hợp lệ làm đối số hoặc thay đổi điều kiện.

BIÊN TẬP:

Dưới đây là một ví dụ về truy vấn giới hạn thời gian dựa trên câu hỏi:

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

CHỈNH SỬA: cột dấu thời gian

Trong trường hợp sử dụng dấu thời gian java.sql.TimestampPreparedStatement.setTimestamp () , tức là:

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

bây giờ điều kiện của tôi là chọn * từ xcart_orders trong đó status = 'Q' AND date = CURDATE (). bây giờ cũng chỉ hiển thị bằng không
Krishna Veni

@krishnaveni bạn đang cố gắng chọn bản ghi nào?
tenorsax

date (11111111,123456767,122333344) và status = (Q, Q, Q) .. tất cả đều được lưu trong cơ sở dữ liệu của tôi. bây giờ tôi muốn kiểm tra truy vấn và lấy giá trị đếm và hiển thị trên bảng điều khiển của tôi (tức là) bao nhiêu dữ liệu ngay được kết hợp sau khi trở về giá trị đếm
Krishna Veni

@krishnaveni Nếu bạn muốn tập kết quả bị ràng buộc bởi một ngày nhất định thì hãy sử dụng ngày đó trong truy vấn, nếu không, hãy xóa điều kiện ngày.
tenorsax

trong mã của tôi hoạt động thành công khi ngày ở định dạng yyyy-mm-dd được lưu trong cơ sở dữ liệu của tôi. Nhưng bây giờ ngày của tôi được lưu trong dấu thời gian ở định dạng 1343469690 này. Làm thế nào là nhận được giá trị đếm như thế nào là tôi đã viết một mã ở đây?
Krishna Veni

3

new Date(timestamp.getTime())nên hoạt động, nhưng cách Java 8 ưa thích mới (có thể thanh lịch hơn và kiểu an toàn hơn, cũng như giúp dẫn dắt bạn sử dụng các lớp thời gian mới) là gọi Date.from(timestamp.toInstant()).

(Đừng dựa vào thực tế rằng Timestampbản thân nó là một ví dụ Date; hãy xem giải thích trong phần bình luận của một câu trả lời khác .)


3
    Timestamp tsp = new Timestamp(System.currentTimeMillis());
   java.util.Date dateformat = new java.util.Date(tsp.getTime());

3

Tôi cảm thấy có nghĩa vụ phải trả lời vì các câu trả lời khác dường như là bất khả tri về múi giờ mà một ứng dụng trong thế giới thực không thể có được. Để thực hiện chuyển đổi dấu thời gian sang ngày chính xác khi dấu thời gian và JVM đang sử dụng các múi giờ khác nhau, bạn có thể sử dụng LocalDateTime của Joda Time (hoặc LocalDateTime trong Java8) như sau:

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

Ví dụ dưới đây giả định rằng dấu thời gian là UTC (thường là trường hợp với cơ sở dữ liệu). Trong trường hợp dấu thời gian của bạn ở múi giờ khác, hãy thay đổi tham số múi giờ của toDatecâu lệnh.


2

cố gắng sử dụng mã java này:

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

Giả sử bạn có từ trước java.util.Date date:

Timestamp timestamp = new Timestamp(long);
date.setTime( l_timestamp.getTime() );

0

Bạn có thể sử dụng phương pháp này để lấy Ngày từ Dấu thời gian và Múi giờ của khu vực cụ thể.

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;

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.