Come ottengo la differenza di giorni tra 2 date in SQLite? Ho già provato qualcosa di simile:
SELECT Date('now') - DateCreated FROM Payment
Restituisce 0 ogni volta.
Come ottengo la differenza di giorni tra 2 date in SQLite? Ho già provato qualcosa di simile:
SELECT Date('now') - DateCreated FROM Payment
Restituisce 0 ogni volta.
Risposte:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
DateCreatedin UTC. Se, invece, è l'ora locale, devi convertirla julianday('now')in ora locale. Non sono riuscito a trovare da nessuna parte che contenesse queste informazioni. Se ti julianday('now') - julianday(DateCreated)piace che questo post suggerisce con una data memorizzata nell'ora locale, la tua risposta sarà diversa dal tuo offset dal GMT e sarà sbagliata. Anche se forse non è la migliore pratica per memorizzare le date nell'ora locale, può comunque accadere in app in cui i fusi orari non contano (tranne quando lo strumento con cui stai lavorando li impone su di te, come qui).
julianday('now') - julianday(DateCreated, 'utc'), per rendere sia UTC, non funziona allo stesso modo di farlo julianday('now', 'localtime') - julianday(DateCreated). Il primo non tiene conto dei giorni di DST e aggiungerà un'ora in più alle date create in marzo-novembre. Quest'ultimo in realtà lo spiega. stackoverflow.com/questions/41007455/...
Differenza in giorni
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) As Integer)
Differenza in ore
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 As Integer)
Differenza in minuti
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 As Integer)
Differenza in secondi
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 * 60 As Integer)
Entrambe le risposte forniscono soluzioni un po 'più complesse, come devono essere. Supponiamo che il pagamento sia stato creato il January 6, 2013. E vogliamo conoscere la differenza tra questa data e quella odierna.
sqlite> SELECT julianday() - julianday('2013-01-06');
34.7978485878557
La differenza è di 34 giorni. Possiamo usare julianday('now')per una migliore chiarezza. In altre parole, non abbiamo bisogno di mettere
date()o datetime()funzioni come parametri per julianday()
funzionare.
La documentazione di SQLite è un ottimo riferimento e la pagina DateAndTimeFunctions è buona da aggiungere ai segnalibri.
È anche utile ricordare che è abbastanza facile giocare con le query con l'utilità della riga di comando sqlite:
sqlite> select julianday(datetime('now'));
2454788.09219907
sqlite> select datetime(julianday(datetime('now')));
2008-11-17 14:13:55
Questa risposta è un po 'prolissa e la documentazione non te lo dirà (perché presumono che tu stia memorizzando le tue date come date UTC nel database), ma la risposta a questa domanda dipende in gran parte dal fuso orario in cui le tue date sono memorizzate in. Inoltre, non si utilizza Date('now'), ma si utilizza la julianday()funzione, per calcolare entrambe le date rispetto a una data comune, quindi sottrarre la differenza di tali risultati l'uno dall'altro.
Se le tue date sono memorizzate in UTC:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
Questo è ciò che ha la risposta in cima alla classifica ed è anche nella documentazione . È solo una parte dell'immagine, e una risposta molto semplicistica, se me lo chiedi.
Se le tue date sono memorizzate nell'ora locale, l'utilizzo del codice sopra renderà la tua risposta SBAGLIATA per il numero di ore in cui il tuo offset GMT è. Se ti trovi negli Stati Uniti orientali come me, che è GMT -5, il tuo risultato avrà 5 ore in più. E se provi a renderti DateCreatedconforme a UTC perché julianday('now')va contro una data GMT:
SELECT julianday('now') - julianday(DateCreated, 'utc') FROM Payment;
Questo ha un bug in cui aggiungerà un'ora per un DateCreatedche è durante l'ora legale (marzo-novembre). Supponi che "adesso" sia a mezzogiorno in un giorno non DST e che hai creato qualcosa a giugno (durante l'ora legale) a mezzogiorno, il risultato darà 1 ora di distanza, invece di 0 ore, per la parte delle ore. Dovresti scrivere una funzione nel codice dell'applicazione che visualizza il risultato per modificare il risultato e sottrarre un'ora dalle date dell'ora legale. L'ho fatto, fino a quando non ho capito che c'era una soluzione migliore a quel problema che stavo avendo: SQLite vs Oracle - Calcolo delle differenze di data - ore
Invece, come mi è stato fatto notare, per le date memorizzate nell'ora locale, fai corrispondere entrambe all'ora locale:
SELECT julianday('now', 'localtime') - julianday(DateCreated) FROM Payment;
Oppure aggiungi 'Z'all'ora locale:
julianday(datetime('now', 'localtime')||'Z') - julianday(CREATED_DATE||'Z')
Entrambi sembrano compensare e non aggiungere l'ora extra per le date dell'ora legale e fare una sottrazione diretta - in modo che l'elemento creato a mezzogiorno in un giorno dell'ora legale, quando si controlla a mezzogiorno in un giorno non ora legale, non riceverà un'ora in più quando eseguire il calcolo.
E mentre riconosco che la maggior parte dirà di non memorizzare le date nell'ora locale nel database e di memorizzarle in UTC in modo da non incappare in questo, beh non tutte le applicazioni hanno un pubblico mondiale e non tutti i programmatori vogliono per passare attraverso la conversione di OGNI data nel loro sistema in UTC e viceversa ogni volta che eseguono un GET o SET nel database e si occupano di capire se qualcosa è locale o in UTC.
Solo una nota per scrivere le funzioni dell'orologio. Per coloro che cercano le ore lavorate, una modifica molto semplice di questo consente di visualizzare le ore più i minuti come percentuale di 60 come la maggior parte delle aziende di libro paga lo desidera.
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
Se vuoi l'ora nel formato 00:00: l'ho risolto in questo modo:
select strftime('%H:%M',CAST ((julianday(FinishTime) - julianday(StartTime)) AS REAL),'12:00') from something
Dato che il formato della data è il seguente: "AAAA-MM-GG HH: MM: SS", se devi trovare la differenza tra due date in numero di mesi:
(strftime('%m', date1) + 12*strftime('%Y', date1)) -
(strftime('%m', date2) + 12*strftime('%Y', date2))
In primo luogo, non è chiaro quale sia il formato della data. C'è già una risposta coinvolgente strftime("%s").
Mi piace espandere questa risposta.
SQLite ha solo le seguenti classi di archiviazione: NULL, INTEGER, REAL, TEXT o BLOB. Per semplificare le cose, presumo che le date siano REALI contenenti i secondi dal 1970-01-01. Ecco uno schema di esempio per il quale inserirò i dati di esempio del "1 dicembre 2018":
CREATE TABLE Payment (DateCreated REAL);
INSERT INTO Payment VALUES (strftime("%s", "2018-12-01"));
Ora calcoliamo la differenza di data tra il "1 ° dicembre 2018" e ora (mentre scrivo, è mezzogiorno del 12 dicembre 2018):
Differenza di data in giorni:
SELECT (strftime("%s", "now") - DateCreated) / 86400.0 FROM Payment;
-- Output: 11.066875
Differenza di data in ore:
SELECT (strftime("%s", "now") - DateCreated) / 3600.0 FROM Payment;
-- Output: 265.606388888889
Differenza di data in minuti:
SELECT (strftime("%s", "now") - DateCreated) / 60.0 FROM Payment;
-- Output: 15936.4833333333
Differenza di data in secondi:
SELECT (strftime("%s", "now") - DateCreated) FROM Payment;
-- Output: 956195.0
Se vuoi registrare tra giorni,
select count(col_Name) from dataset where cast(julianday("now")- julianday(_Last_updated) as int)<=0;
Nel mio caso, devo calcolare la differenza in minuti e julianday()non fornisce un valore preciso. Invece, utilizzo strftime():
SELECT (strftime('%s', [UserEnd]) - strftime('%s', [UserStart])) / 60
Entrambe le date vengono convertite in unixtime (secondi), quindi sottratte per ottenere il valore in secondi tra le due date. Quindi, dividerlo per 60.