Java Timestamp - Làm cách nào để tạo một Timestamp có ngày 23/09/2007?


Câu trả lời:


154

Bởi Timestamp, tôi đoán bạn có nghĩa là java.sql.Timestamp. Bạn sẽ nhận thấy rằng lớp này có một hàm tạo chấp nhận một longđối số. Bạn có thể phân tích cú pháp này bằng cách sử dụng DateFormatlớp:

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

1
Định dạng ngày ISO bình thường là yyyy-MM-dd, nếu không thì tuyệt vời!
vidstige

1
Dấu thời gian mới (thời gian); đưa ra lỗi không có hàm tạo nào như thế này nhận giá trị dài :(
Bhanu Sharma

1
@Bhanu Tài liệu cho thấy điều này có giá trị lâu dài và dường như hoạt động chính xác: docs.oracle.com/javase/7/docs/api/java/sql/…
Hazok

FYI, người già lớp ngày thời gian khủng khiếp phiền hà như java.util.Date, java.util.Calendarjava.text.SimpleDateFormatbây giờ là di sản , thay thế bởi sự java.time class built vào Java 8 và sau đó. Xem Hướng dẫn của Oracle .
Basil Bourque

121

Cái này thì sao?

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

1
Dấu thời gian Timestamp = Timestamp.valueOf ("2007-09-23 10: 10: 10.0"); đang hiển thị phương pháp valueOf là undefined cho các loại Timestamp trong JDK 7
Ashish Ratan

Dấu thời gian mới (thời gian); đưa ra lỗi không có hàm tạo nào như thế này nhận giá trị chuỗi :(
Bhanu Sharma

@Bhanu Hàm khởi tạo lấy thời gian unix tính bằng mili giây. Sử dụng phương thức tĩnh valueOf nếu bạn muốn lấy dấu thời gian từ một chuỗi.
Hazok

4
Đây dường như là câu trả lời tốt nhất cho câu hỏi.
Hazok

1
Câu trả lời tốt nhất là Date, không được dùng nữa, là một phương pháp không tốt để sử dụng nó. Câu trả lời này là tốt hơn. Cảm ơn bạn
Alberici

18

Ý bạn là gì dấu thời gian? Nếu ý bạn là mili giây kể từ kỷ nguyên Unix:

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

Nếu bạn muốn một đối tượng java.sql.Timestamp thực tế:

Timestamp ts = new Timestamp(millis);

2
SAI và sẽ không biên dịch! Lỗi biên dịch: 09 là một số bát phân, nhưng 9 nằm ngoài phạm vi đối với số bát phân. Logic lỗi: tháng là 0-based, bạn sẽ nhận được ngày 23 tháng 10 năm 2007
user85421

Tôi không thể gặp lỗi logic nếu nó không biên dịch. :) Nghiêm túc, bắt tốt, Carlos. Bát phân tôi đã bắt trước đây nhưng dù sao đã dán sai. :(
Matthew Flaschen

Trên thực tế các nhà xây dựng Timestamp được depricated thay vì bạn có thể sử dụng () phương pháp Timestamp.valueOf
Shiva Komuravelly

@ShivaKomuravelly không phải tất cả timestamp constructor đang bị phản đối và ít nhất không mà mất miễn là mili giây, constructor mà mất ngày như là đối số bị phản đối
không có tên

Và có một hằng số cho điều đó (thay vì tháng = 9):Calendar.SEPTEMBER
Guillaume Husta,

11

tl; dr

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

java.time

Hãy cập nhật trang này bằng cách hiển thị mã bằng khung công tác java.time được tích hợp trong Java 8 trở lên.

Các lớp mới này được lấy cảm hứng từ Joda-Time , được định nghĩa bởi JSR 310 và được mở rộng bởi dự án ThreeTen-Extra . Họ thay thế các lớp date-time cũ nổi tiếng rắc rối được đóng gói bằng các phiên bản Java ban đầu.

Trong java.time, an Instantlà một thời điểm trên dòng thời gian theo giờ UTC. A ZonedDateTimelà một Instant được điều chỉnh thành múi giờ ( ZoneId).

Múi giờ là rất quan trọng ở đây. September 23, 2007Không thể dịch ngày của thành một thời điểm trên dòng thời gian mà không áp dụng múi giờ. Hãy cân nhắc rằng một ngày mới ở Paris đến sớm hơn ở Montréal, nơi nó vẫn là “ngày hôm qua”.

Ngoài ra, java.sql.Timestamp đại diện cho cả ngày và giờ trong ngày. Vì vậy, chúng ta phải tiêm một thời gian trong ngày để đi cùng với ngày. Chúng tôi giả định rằng bạn muốn khoảnh khắc đầu tiên trong ngày là thời gian trong ngày. Lưu ý rằng đây không phải lúc nào cũng là lúc 00:00:00.0vì Giờ tiết kiệm ánh sáng ban ngày và có thể có những bất thường khác.

Lưu ý rằng không giống như lớp java.util.Date cũ và không giống như Joda-Time, các kiểu java.time có độ phân giải là nano giây chứ không phải mili giây. Điều này phù hợp với độ phân giải của java.sql.Timestamp.

Lưu ý rằng java.sql.Timestamp có thói quen xấu là áp dụng ngầm múi giờ mặc định hiện tại của JVM cho giá trị ngày-giờ của nó khi tạo biểu diễn chuỗi thông qua toStringphương thức của nó . Ở đây bạn thấy America/Los_Angelesmúi giờ của tôi được áp dụng. Ngược lại, các lớp java.time lành mạnh hơn, sử dụng các định dạng ISO 8601 tiêu chuẩn .

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

Đổ vào bảng điều khiển.

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

Khi chạy.

d: 2007-09-23 = zdt: 2007-09-23T00: 00-04: 00 [Châu Mỹ / Montreal] = tức thì: 2007-09-23T04: 00: 00Z = ts: 2007-09-22 21:00: 00.0

Nhân tiện, kể từ JDBC 4.2, bạn có thể sử dụng trực tiếp các loại java.time. Không cần java.sql.Timestamp.

  • PreparedStatement.setObject
  • ResultSet.getObject

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 .

Bạn có thể trao đổi các đối tượng java.time trực tiếp với cơ sở dữ liệu của mình. Sử dụng trình điều khiển JDBC tương thích với JDBC 4.2 trở lên. Không cần chuỗi, không cần java.sql.*lớp.

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

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 .


3
Tôi tự hỏi làm cách nào tôi có thể yêu cầu OP hoặc mod đánh dấu câu trả lời của bạn là câu trả lời đúng. Câu trả lời được chấp nhận đã quá lỗi thời.
sttaq

Rất tốt, ngoại trừ một lỗi đánh máy. asStartOfDay () phải là atStartOfDay ().
Tullochgorum

@Tullochgorum Đã sửa. Cảm ơn. FYI, trên Stack Overflow, bạn có thể tự mình thực hiện các chỉnh sửa như vậy, nếu bạn có khuynh hướng như vậy.
Basil Bourque

5

Bạn cũng có thể làm như sau:

// 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
SAI: hãy thử System.out.println của kết quả! Bạn sẽ nhận được một cái gì đó như: "2009-10-23 15: 26: 56.171" Tháng dựa trên 0 nên ngày 9 là tháng 10!
user85421

Tôi biết một trong những hằng số đó là không, cảm ơn. Đã cập nhật bài đăng.
Alex

1
Oh, và tôi đã đặt 'chưa được kiểm tra' :)
Alex

4

Theo API, hàm tạo chấp nhận năm, tháng, v.v. không được dùng nữa. Thay vào đó, bạn nên sử dụng Constructor chấp nhận một long. Bạn có thể sử dụng triển khai Lịch để xây dựng ngày bạn muốn và truy cập vào biểu diễn thời gian dài hạn, chẳng hạn với phương thức getTimeInMillis .


1

Vì lợi ích hoàn chỉnh, cũng là một giải pháp với Joda-Time phiên bản 2.5 và DateTimelớp của nó :

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

1
Câu trả lời hay, nhưng bạn đã bỏ lỡ một phần quan trọng : múi giờ . Nếu bạn bỏ qua múi giờ, múi giờ mặc định hiện tại của JVM sẽ được áp dụng cho DateTimeđối tượng. Điều đó có nghĩa là kết quả của bạn sẽ khác nhau trên các máy tính khác nhau hoặc cấu hình của cài đặt hệ điều hành máy chủ hoặc JVM. Để có kết quả có thể đoán trước, hãy chuyển múi giờ cho hàm tạo đó DateTime. Chọn tên múi giờ thích hợp cho ý định của bạn. Ví dụ, DateTimeZone.forID( "America/Montreal" )hoặc DateTimeZone.UTC.
Basil Bourque

Mã đó có thể ngắn gọn hơn. Không cần chuyển đổi sang java.util.Date để nhận và vượt qua mili giây-kể từ khi- epoch . Chỉ cần hỏi DateTimeđối tượng về kỷ nguyên mili giây của nó. Thay thế .toDate().getTime()bằng .getMillis().
Basil Bourque

@BasilBourque Tùy thuộc vào hoàn cảnh, bạn có thể muốn bỏ múi giờ để có kết quả dự đoán. "Theo múi giờ hiện tại của bạn" có thể là một kết quả hoàn toàn hợp lý và có thể dự đoán được. Tại sao lại hardcode một múi giờ hoặc yêu cầu người dùng của bạn đặt múi giờ theo cách thủ công khi máy tính của họ đã được đặt múi giờ? Chắc chắn tôi sẽ khá ngạc nhiên nếu một ứng dụng trên máy tính của tôi bắt đầu xuất hiện ngày tháng được điều chỉnh theo múi giờ Châu Mỹ / Montreal.
dan carter

@dancarter Việc bỏ qua múi giờ tùy chọn dẫn đến nhầm lẫn. Sự thiếu sót làm tăng sự mơ hồ của (a) lập trình viên có ý định dựa vào mặc định ngầm định hay (b) lập trình viên không xem xét các vấn đề về múi giờ (như tất cả đều quá phổ biến). Nếu bạn thực sự muốn sử dụng múi giờ mặc định hiện tại của JVM, hãy nói rõ ràng như vậy bằng cách gọi DateTimeZone.getDefault()và chuyển kết quả làm đối số tùy chọn. (Nhân tiện, ditto cho Locale.getDefault(), cùng một vấn đề về sự mơ hồ của các đối số tùy chọn.)
Basil Bourque

-1

Một câu trả lời chung chung hơn sẽ là nhập java.util.Date, sau đó khi bạn cần đặt timestampbằng với ngày hiện tại, chỉ cần đặt bằng new Date().


bởi vì ** Date ("string"); ** không được dùng nữa
Ashish Ratan
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.