2008-11-14 39 views
75

Làm cách nào để có được sự khác biệt trong những ngày giữa 2 ngày trong SQLite? Tôi đã thử một cái gì đó như thế này:Sự khác nhau giữa 2 ngày trong SQLite

SELECT Date('now') - DateCreated FROM Payment 

Nó trả về 0 mỗi lần.

Trả lời

86
SELECT julianday('now') - julianday(DateCreated) FROM Payment; 
+8

Lưu ý rằng mặc dù những gì tên hàm có thể làm cho một suy nghĩ, điều này có granularity cao hơn ngày. Đó là một số ngày, nhưng có thể phân số. – lindes

+7

Hãy nhớ rằng julianday trả về số (phân số) của 'ngày' - tức là 24 giờ, kể từ * giờ trưa * UTC vào ngày xuất phát. Đó thường không phải những gì bạn cần, trừ khi bạn tình cờ sống 12 giờ về phía tây Greenwich. Ví dụ. nếu bạn sống ở London, sáng nay là trên cùng một julianday như chiều hôm qua. – JulianSymes

+1

Nó hoạt động nếu 'DateCreated' của bạn ở dạng UTC. Nếu, thay vào đó, đó là giờ địa phương, bạn phải chuyển đổi 'julianday ('now')' thành giờ địa phương. Tôi không thể tìm thấy bất cứ nơi nào có thông tin này. Nếu bạn làm 'julianday ('now') - julianday (DateCreated)' giống như bài viết này gợi ý với một ngày được lưu trữ trong giờ địa phương, câu trả lời của bạn sẽ bị tắt bởi offset của bạn từ GMT và sẽ sai. Mặc dù có thể không thực hành tốt nhất để lưu trữ ngày trong giờ địa phương, nhưng vẫn có thể xảy ra trong các ứng dụng mà múi giờ không quan trọng (trừ khi công cụ bạn đang làm việc với lực lượng chúng trên bạn, như ở đây). – vapcguy

19

Wiki SQLite là tham chiếu tuyệt vời và trang DateAndTimeFunctions là trang hay nhất để đánh dấu trang. Nó cũng hữu ích để nhớ rằng nó là khá dễ dàng để chơi với các truy vấn với các tiện ích dòng lệnh sql:

sqlite> select julianday(datetime('now')); 
2454788.09219907 
sqlite> select datetime(julianday(datetime('now'))); 
2008-11-17 14:13:55 
+1

Vì trang này đi kèm với xếp hạng công cụ tìm kiếm google, ở đây liên kết hiện tại: https: //www.sqlite. org/lang_datefunc.html – markusN

+1

Đã sửa lỗi.Cảm ơn @markusN – cosimo

29

Cả hai câu trả lời cung cấp các giải pháp một chút phức tạp hơn, khi họ cần phải được. Giả sử thanh toán được tạo trên January 6, 2013. Và chúng tôi muốn biết sự khác biệt giữa ngày này và hôm nay.

sqlite> SELECT julianday() - julianday('2013-01-06'); 
34.7978485878557 

Sự khác biệt là 34 ngày. Chúng tôi có thể sử dụng julianday('now') cho rõ ràng hơn. Nói cách khác, chúng tôi không cần phải đặt các hàm date() hoặc datetime() làm tham số cho hàm julianday() .

23

khác biệt trong những ngày

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate) 
) As Integer) 

Difference Trong giờ

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate) 
) * 24 As Integer) 

Difference Trong Minutes

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate) 
) * 24 * 60 As Integer) 

Difference Trong Giây

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate) 
) * 24 * 60 * 60 As Integer) 
+1

cho phiên bản sqlite 3.12.0 biểu thức truyền có AS TYPE bên trong dấu ngoặc đơn. ví dụ. "Chọn Cast (5.6 As Integer);" https://www.sqlite.org/lang_expr.html#castexpr Các ví dụ thực sự hữu ích khác. – rob

+0

Cảm ơn bạn @rob. Ai đó đã đề xuất chỉnh sửa tôi như thế trước đây. Nhưng khi tôi thử nó trong Sqlitebrowser, nó không hoạt động. Có lẽ đó là vì phiên bản cũ hơn. Vì vậy, tôi giữ nó như nó là .. – Sayka

+0

Tôi chỉ cần sử dụng SQLitebrowser và có lỗi cướp đề cập .. Tôi có thể chỉnh sửa bài viết của bạn với từ ngữ hiện đại? – Noumenon

2

Chỉ cần một lưu ý cho các văn bản chức năng timeclock. Đối với những người tìm kiếm giờ làm việc, một sự thay đổi rất đơn giản của việc này được tính theo giờ cộng với số phút được hiển thị dưới dạng phần trăm là 60 vì hầu hết các công ty trả lương đều muốn.

CAST ((julianday(clockOUT) - julianday(clockIN)) * 24 AS REAL) AS HoursWorked

Clock In   Clock Out   HoursWorked 
2016-08-07 11:56 2016-08-07 18:46 6.83333332836628 
+0

Truy vấn nhỏ gọn, tuy nhiên, mặc dù :) – vapcguy

3

Câu trả lời này là một chút dài dòng, và các tài liệu sẽ không nói với bạn điều này (vì họ cho rằng bạn đang lưu trữ ngày của bạn như UTC ngày trong cơ sở dữ liệu), nhưng câu trả lời cho Bạn cũng không sử dụng Date('now'), nhưng sử dụng hàm julianday(), để tính cả hai ngày ngược lại với một ngày chung, sau đó trừ đi sự khác biệt của các kết quả đó với nhau.

Nếu ngày của bạn được lưu trữ trong UTC:

SELECT julianday('now') - julianday(DateCreated) FROM Payment; 

Đây là những gì các câu trả lời hàng đầu xếp hạng có, và cũng có thể là trong the documentation. Nó chỉ là một phần của bức tranh, và một câu trả lời rất đơn giản, nếu bạn hỏi tôi.

Nếu ngày của bạn được lưu trữ theo giờ địa phương, sử dụng mã ở trên sẽ làm cho câu trả lời của bạn WRONG theo số giờ bù giờ GMT của bạn. Nếu bạn đang ở Đông Mỹ như tôi, đó là GMT -5, kết quả của bạn sẽ có thêm 5 giờ vào đó. Và nếu bạn cố gắng làm cho DateCreated phù hợp với UTC vì julianday('now') đi ngược lại một ngày giờ:

SELECT julianday('now') - julianday(DateCreated, 'utc') FROM Payment; 

này có một lỗi nơi nó sẽ thêm một tiếng đồng hồ cho một DateCreated đó là trong Daylight Savings Time (tháng tháng mười một). Nói rằng "bây giờ" là vào buổi trưa vào một ngày không DST, và bạn tạo ra một cái gì đó trở lại trong tháng sáu (trong DST) vào buổi trưa, kết quả của bạn sẽ cho 1 giờ ngoài, thay vì 0 giờ, cho phần giờ. Bạn sẽ phải viết một hàm trong mã của ứng dụng đang hiển thị kết quả để sửa đổi kết quả và trừ một giờ từ ngày DST. Tôi đã làm điều đó, cho đến khi tôi nhận ra có một giải pháp tốt hơn cho vấn đề đó mà tôi đã có: SQLite vs. Oracle - Calculating date differences - hours

Thay vào đó, như đã chỉ ra cho tôi, cho những ngày được lưu trữ theo giờ địa phương, làm cho cả hai trận đấu tới giờ địa phương:

SELECT julianday('now', 'localtime') - julianday(DateCreated) FROM Payment; 

Hoặc thêm 'Z' thời gian cục bộ:

julianday(datetime('now', 'localtime')||'Z') - julianday(CREATED_DATE||'Z') 

Cả hai dường như để bù đắp và không thêm giờ thêm cho những ngày DST và làm thẳng trừ - vì vậy mục mà tạo ra vào buổi trưa vào một ngày DST, khi kiểm tra vào buổi trưa trên không phải DS T ngày, sẽ không nhận được thêm một giờ khi thực hiện phép tính. Trong khi tôi nhận ra hầu hết sẽ nói không lưu trữ ngày trong giờ địa phương trong cơ sở dữ liệu của bạn và lưu trữ chúng trong UTC để bạn không gặp phải vấn đề này, cũng không phải mọi ứng dụng đều có đối tượng trên toàn thế giới, và không phải mọi lập trình viên đều muốn chuyển đổi M EVI ngày trong hệ thống của họ sang UTC và ngược lại mỗi khi họ thực hiện GET hoặc SET trong cơ sở dữ liệu và xử lý việc tìm ra một thứ gì đó cục bộ hoặc trong UTC.

+0

" Nó chỉ là một phần của hình ảnh, và một câu trả lời rất đơn giản, nếu bạn hỏi tôi. " Vâng bạn đã đúng. Nhưng câu trả lời của tôi đã được đưa ra 3 phút sau khi anh ấy hỏi câu hỏi của anh ấy khi bạn đến sau hai năm. Đơn giản nhưng cô ấy dường như phù hợp với anh ta. – Fred

+1

@Fred Fair đủ. Nhưng nó thực sự đã kết thúc đưa tôi đi xe, như tôi đã mô tả ở trên, và vì vậy đã không giúp tôi. Tôi muốn chắc chắn rằng bất cứ ai nhìn thấy điều này trong tương lai đều biết chính xác những gì đang xảy ra để họ không đánh những cạm bẫy tôi đã làm - hoặc, nếu họ đã làm, họ sẽ biết cách thoát ra khỏi chúng. – vapcguy

1

Nếu bạn muốn thời gian ở định dạng 00:00: Tôi giải quyết nó như thế:

select strftime('%H:%M',CAST ((julianday(FinishTime) - julianday(StartTime)) AS REAL),'12:00') from something 
Các vấn đề liên quan