Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Múi giờ dấu thời gian của Java Date và MySQL

tl; dr

myPreparedStatement
.setObject(  
    … ,                                   // Specify which placeholder `?` in your SQL statement. 
    OffsetDateTime.now( ZoneOffset.UTC )  // Capture the current moment as seen in the wall-clock time of UTC (an offset-from-UTC of zero).
) ;

Tránh các lớp ngày-giờ kế thừa

Bạn đang sử dụng các lớp date-time khủng khiếp đã được thay thế nhiều năm trước bởi java.time các lớp học.

Không bao giờ sử dụng Date hoặc Timestamp .

UTC

Ghi lại khoảnh khắc hiện tại, theo giờ UTC. Hầu hết các cơ sở dữ liệu lưu trữ một khoảnh khắc trong UTC. Và nói chung, bạn nên thực hiện hầu hết logic nghiệp vụ của mình, gỡ lỗi, ghi nhật ký, lưu trữ và trao đổi dữ liệu trong UTC.

OffsetDateTime

Thể hiện một khoảnh khắc bằng offset-from-UTC bằng cách sử dụng OffsetDateTime được đặt tên phù hợp lớp.

Chúng tôi muốn chính UTC, hoặc một khoảng chênh lệch bằng không. Chúng ta có thể sử dụng một hằng số cho điều đó, ZoneOffset.UTC .

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ) ;

JDBC 4.2

Kể từ JDBC 4.2, chúng tôi có thể trao đổi trực tiếp java.time các đối tượng với cơ sở dữ liệu.

Để lưu khoảnh khắc này vào một cột có kiểu dữ liệu tương tự như TIMESTAMP WITH TIME ZONE theo tiêu chuẩn SQL :

myPreparedStatement.setObject( … , odt ) ;

Truy xuất:

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

ZonedDateTime

Để trình bày khoảnh khắc đã truy xuất này cho người dùng, bạn có thể muốn điều chỉnh theo múi giờ dự kiến ​​/ mong muốn của người dùng.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

Không bao giờ dựa vào múi giờ mặc định

Lưu ý trong đoạn mã ở trên rằng chúng tôi luôn chỉ định khoảng cách hoặc vùng mong muốn / mong đợi.

Nếu bạn không chỉ định, một khoảng chênh lệch hoặc vùng được áp dụng ngầm. Tốt hơn nên chỉ rõ ý định của bạn một cách rõ ràng vì mặc định hiện tại của JVM, cơ sở dữ liệu và hệ điều hành máy chủ lưu trữ đều nằm ngoài tầm tay của bạn với tư cách là một lập trình viên. Điều đó có nghĩa là mã dựa trên mặc định sẽ khác nhau về hành vi trong thời gian chạy.

Java 6 &7

Cùng một người đàn ông, Stephen Colebourne, người dẫn đầu JSR 310 và java.time triển khai, cũng như Joda-Time nổi tiếng dự án, cũng dẫn đầu một dự án khác, ThreeTen-Backport . Hầu hết các java.time chức năng được chuyển ngược lại sang Java 6 &7 trong thư viện này, với API gần như giống hệt nhau.

Vì vậy, hãy thực hiện tất cả công việc của bạn trong các lớp cổng sau. Sau đó, vào giây phút cuối cùng, hãy chuyển đổi thành / từ java.sql.Timestamp qua DateTimeUtils lớp.

Các phương pháp chuyển đổi đó chủ yếu sử dụng Instant các đối tượng. Một Instant là một thời điểm trong UTC, luôn luôn ở UTC. Bạn có thể điều chỉnh từ OffsetDateTime của mình sang UTC bằng cách trích xuất một Instant . Instant lớp là lớp khối xây dựng cơ bản trong java.time , với OffsetDateDate linh hoạt hơn, chẳng hạn như các mẫu định dạng thay thế khi tạo một chuỗi. Nhưng cả hai InstantOffsetDateTime đại diện cho một thời điểm, một điểm trên dòng thời gian.

Instant instant = odt.toInstant() ;  
java.sql.Timestamp ts = org.threeten.bp.DateTimeUtils.toSqlTimestamp( instant ) ;

Đi theo hướng khác, truy xuất Timestamp từ cơ sở dữ liệu của bạn, sau đó chuyển đổi ngay lập tức sang Instant .

java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
Instant instant = org.threeten.bp.DateTimeUtils.toInstant( ts ) ;

Giới thiệu về java.time

java.time khung công tác được xây dựng trong Java 8 trở lên. Các lớp này thay thế cho kế thừa cũ rắc rối các lớp date-time chẳng hạn như java.util.Date , Calendar & SimpleDateFormat .

Joda-Time dự án, hiện đang ở chế độ bảo trì , khuyên bạn nên di chuyển sang java.time các lớp học.

Để 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 java.time đối tượng trực tiếp với cơ sở dữ liệu của bạn. Sử dụng trình điều khiển JDBC tuân thủ JDBC 4.2 hoặc sau đó. Không cần chuỗi, không cần java.sql.* các lớp học.

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

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ố lớp hữu ích tại đây, chẳng hạn như Interval , YearWeek , YearQuarter khác .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nhanh chóng thêm bản sao của một cột vào bảng MySQL

  2. Không thể khởi động MySQL từ thiết bị đầu cuối

  3. Làm thế nào để so sánh một ngày từ mySQL với ngày hiện tại trong java?

  4. Flask-Sqlalchemy:Truy vấn DB không trả về dữ liệu mới

  5. Thư mục mysqld_safe '/ var / run / mysqld' cho tệp ổ cắm UNIX không tồn tại