SQLite'da 2 tarih arasındaki gün farkını nasıl elde ederim? Zaten böyle bir şey denedim:
SELECT Date('now') - DateCreated FROM Payment
Her seferinde 0 döndürür.
SQLite'da 2 tarih arasındaki gün farkını nasıl elde ederim? Zaten böyle bir şey denedim:
SELECT Date('now') - DateCreated FROM Payment
Her seferinde 0 döndürür.
Yanıtlar:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
DateCreated
UTC'de ise çalışır . Bunun yerine yerel saat ise, yerel saate çevirmeniz julianday('now')
gerekir. Bu bilgiye sahip hiçbir yer bulamadım. Bunu yaparsanız julianday('now') - julianday(DateCreated)
bu yayını yerel saatle saklanan bir tarihle anlaşılacağı gibi, cevabın sizin GMT ofset tarafından kapalı olacak ve yanlış olacaktır. Tarihleri yerel saatte depolamak için en iyi uygulama olmasa da, saat dilimlerinin önemli olmadığı uygulamalarda yine de olabilir (burada olduğu gibi, birlikte çalıştığınız aracın onları size zorlaması dışında).
julianday('now') - julianday(DateCreated, 'utc')
, her iki UTC'yi de yapmak için, aynı şekilde çalışmaz julianday('now', 'localtime') - julianday(DateCreated)
. Birincisi, DST günlerini hesaba katmaz ve Mart-Kasım'da oluşturulan tarihlere fazladan bir saat ekler. İkincisi aslında bunu açıklıyor. stackoverflow.com/questions/41007455/…
Günlerdeki Fark
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) As Integer)
Saat Farkı
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 As Integer)
Dakika Farkı
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 As Integer)
Saniyedeki Fark
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 * 60 As Integer)
Her iki cevap da olması gerektiği gibi biraz daha karmaşık çözümler sunar. Ödemenin tarihinde oluşturulduğunu varsayalım January 6, 2013
. Ve bu tarih ile bugün arasındaki farkı bilmek istiyoruz.
sqlite> SELECT julianday() - julianday('2013-01-06');
34.7978485878557
Aradaki fark 34 gündür. Daha julianday('now')
iyi netlik için kullanabiliriz . Başka bir deyişle, çalışmak için parametre olarak koymamız date()
veya datetime()
işlev görmemiz gerekmez
julianday()
.
SQLite belgeleri harika bir referanstır ve DateAndTimeFunctions sayfası yer imlerine eklemek için iyi bir sayfadır.
Ayrıca sqlite komut satırı yardımcı programıyla sorgularla oynamanın oldukça kolay olduğunu hatırlamakta fayda var:
sqlite> select julianday(datetime('now'));
2454788.09219907
sqlite> select datetime(julianday(datetime('now')));
2008-11-17 14:13:55
Bu cevap biraz uzun solukludur ve belgeler size bunu söylemeyecektir (çünkü tarihlerinizi veritabanında UTC tarihleri olarak sakladığınızı varsayarlar), ancak bu sorunun cevabı büyük ölçüde tarihlerinizin depolandığı saat dilimine bağlıdır. Ayrıca kullanmazsınız Date('now')
, ancakjulianday()
, her iki tarihi de ortak bir tarihe göre hesaplamak işlevi , ardından bu sonuçların birbirinden farkını çıkarırsınız.
Tarihleriniz UTC olarak saklanıyorsa:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
Bu, en üst sıradaki yanıtın sahip olduğu şeydir ve ayrıca belgelerde bulunur . Bana sorarsan, resmin sadece bir parçası ve çok basit bir cevap.
Tarihleriniz yerel saatte saklanıyorsa, yukarıdaki kodu kullanmak cevabınızı GMT farkınızın kaç saat kadar YANLIŞ yapacaktır . Eğer benim gibi Doğu ABD'deyseniz, GMT -5, sonucunuz üzerine 5 saat eklenecektir. Ve eğer DateCreated
UTC'ye uymaya çalışırsanız, çünkü julianday('now')
GMT tarihine aykırıdır:
SELECT julianday('now') - julianday(DateCreated, 'utc') FROM Payment;
Bu, DateCreated
Yaz Saati Uygulaması (Mart-Kasım) sırasındaki bir saat için bir saat ekleyeceği bir hataya sahiptir . DST olmayan bir günde "şimdi" öğesinin öğlen olduğunu ve Haziran ayında (DST sırasında) öğle vakti bir şey oluşturduğunuzu, sonucunuzun saatler bölümü için 0 saat yerine 1 saat ara vereceğini söyleyin. Sonucu değiştirmek ve DST tarihlerinden bir saat çıkarmak için uygulamanızın koduna sonucu görüntüleyen bir işlev yazmanız gerekir. Bunu, yaşadığım soruna daha iyi bir çözüm olduğunu anlayana kadar yaptım: SQLite ve Oracle - Tarih farklılıklarını hesaplama - saat
Bunun yerine, bana belirtildiği gibi, yerel saatte depolanan tarihler için her ikisini de yerel saatle eşleştirin:
SELECT julianday('now', 'localtime') - julianday(DateCreated) FROM Payment;
Veya 'Z'
yerel saate ekleyin :
julianday(datetime('now', 'localtime')||'Z') - julianday(CREATED_DATE||'Z')
Bunların her ikisi de telafi ediyor gibi görünüyor ve DST tarihleri için fazladan saat eklemiyor ve doğrudan çıkarma yapıyor - böylece DST günü öğle vakti, DST olmayan bir günde öğlen check-in yaparken, ekstra bir saat almayacak. hesaplama yapmak.
Ve çoğunun tarihleri veritabanınızda yerel saatte saklamayın ve bunları UTC'de saklamanızı söyleyeceğimi fark etsem de, bununla karşılaşmazsınız, her uygulamanın dünya çapında bir izleyici kitlesi yoktur ve her programcı istemez. sistemlerindeki HER tarihin UTC'ye dönüştürülmesinden geçmek ve veritabanında her GET veya SET yaptıklarında tekrar geri gitmek ve bir şeyin yerel mi yoksa UTC'de mi olduğunu bulmakla uğraşmak.
Timeclock işlevlerini yazmak için sadece bir not. Çalışılan saatleri arayanlar için, bunun çok basit bir değişikliği, saatleri ve dakikaları çoğu bordro şirketinin istediği gibi 60'ın bir yüzdesi olarak gösterir.
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
00:00 biçiminde saat istiyorsanız: Bunu şu şekilde çözdüm:
select strftime('%H:%M',CAST ((julianday(FinishTime) - julianday(StartTime)) AS REAL),'12:00') from something
Tarih biçiminizin aşağıdaki gibi olduğunu varsayarsak: "YYYY-AA-GG SS: DD: SS", iki tarih arasındaki farkı ay sayısı olarak bulmanız gerekiyorsa:
(strftime('%m', date1) + 12*strftime('%Y', date1)) -
(strftime('%m', date2) + 12*strftime('%Y', date2))
İlk olarak, tarih formatınızın ne olduğu belli değil. Zaten içeren bir cevap var strftime("%s")
.
Bu cevabı genişletmeyi seviyorum.
SQLite yalnızca şu depolama sınıflarına sahiptir: NULL, INTEGER, REAL, TEXT veya BLOB. İşleri basitleştirmek için, tarihlerin GERÇEK olduğunu ve 1970-01-01'den bu yana geçen saniyeleri içerdiğini varsayacağım. İşte "1 Aralık 2018" örnek verilerine koyacağım örnek bir şema:
CREATE TABLE Payment (DateCreated REAL);
INSERT INTO Payment VALUES (strftime("%s", "2018-12-01"));
Şimdi "1 Aralık 2018" ile şimdiki tarih arasındaki tarih farkını bulalım (bunu yazarken 12 Aralık 2018 öğlen):
Gün cinsinden tarih farkı:
SELECT (strftime("%s", "now") - DateCreated) / 86400.0 FROM Payment;
-- Output: 11.066875
Saat cinsinden tarih farkı:
SELECT (strftime("%s", "now") - DateCreated) / 3600.0 FROM Payment;
-- Output: 265.606388888889
Dakika cinsinden tarih farkı:
SELECT (strftime("%s", "now") - DateCreated) / 60.0 FROM Payment;
-- Output: 15936.4833333333
Saniye cinsinden tarih farkı:
SELECT (strftime("%s", "now") - DateCreated) FROM Payment;
-- Output: 956195.0
Günler arasında kayıt istiyorsanız,
select count(col_Name) from dataset where cast(julianday("now")- julianday(_Last_updated) as int)<=0;
Benim durumumda farkı dakika cinsinden hesaplamam gerekiyor ve julianday()
doğru bir değer vermiyor. Bunun yerine kullanıyorum strftime()
:
SELECT (strftime('%s', [UserEnd]) - strftime('%s', [UserStart])) / 60
Her iki tarih de unixtime'a (saniye) dönüştürülür, ardından iki tarih arasında saniye cinsinden değer elde etmek için çıkarılır. Ardından, 60'a bölün.