Como faço para obter a diferença em dias entre 2 datas no SQLite? Já tentei algo assim:
SELECT Date('now') - DateCreated FROM Payment
Ele retorna 0 todas as vezes.
Como faço para obter a diferença em dias entre 2 datas no SQLite? Já tentei algo assim:
SELECT Date('now') - DateCreated FROM Payment
Ele retorna 0 todas as vezes.
Respostas:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
DateCreated
estiver em UTC. Se, em vez disso, for a hora local, você deve converter julianday('now')
para a hora local. Não consegui encontrar em nenhum lugar que tivesse essa informação. Se você julianday('now') - julianday(DateCreated)
gostar desta postagem sugerir com uma data armazenada no horário local, sua resposta estará errada por seu deslocamento do GMT e estará errada. Embora talvez não seja uma prática recomendada armazenar datas no horário local, isso ainda pode acontecer em aplicativos onde os fusos horários não importam (exceto quando a ferramenta com a qual você está trabalhando os impõe, como aqui).
julianday('now') - julianday(DateCreated, 'utc')
, para fazer ambos UTC, não funcionará da mesma maneira que fazer julianday('now', 'localtime') - julianday(DateCreated)
. O primeiro não leva em conta os dias do horário de verão e adicionará uma hora extra às datas criadas em março-novembro. O último realmente explica isso. stackoverflow.com/questions/41007455/…
Diferença em dias
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) As Integer)
Diferença em horas
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 As Integer)
Diferença em minutos
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 As Integer)
Diferença em segundos
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 * 60 As Integer)
Ambas as respostas fornecem soluções um pouco mais complexas, como precisam ser. Digamos que o pagamento foi criado em January 6, 2013
. E queremos saber a diferença entre esta data e hoje.
sqlite> SELECT julianday() - julianday('2013-01-06');
34.7978485878557
A diferença é de 34 dias. Podemos usar julianday('now')
para maior clareza. Em outras palavras, não precisamos colocar
date()
ou datetime()
funções como parâmetros para julianday()
funcionar.
A documentação do SQLite é uma ótima referência e a página DateAndTimeFunctions é uma boa para marcar.
Também é útil lembrar que é muito fácil brincar com as consultas com o utilitário de linha de comando sqlite:
sqlite> select julianday(datetime('now'));
2454788.09219907
sqlite> select datetime(julianday(datetime('now')));
2008-11-17 14:13:55
Esta resposta é um pouco prolixa e a documentação não dirá isso (porque eles assumem que você está armazenando suas datas como datas UTC no banco de dados), mas a resposta a esta pergunta depende muito do fuso horário em que suas datas estão armazenadas in. Você também não usa Date('now')
, mas usa a julianday()
função, para calcular ambas as datas em relação a uma data comum e, em seguida, subtrair a diferença desses resultados entre si.
Se suas datas estiverem armazenadas em UTC:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
Isso é o que a resposta com melhor classificação tem, e também está na documentação . É apenas parte da imagem e uma resposta muito simplista, se você me perguntar.
Se suas datas forem armazenadas no horário local, usar o código acima tornará sua resposta ERRADA pelo número de horas em que seu deslocamento GMT está. Se você estiver no leste dos EUA como eu, que é GMT -5, seu resultado terá 5 horas adicionadas. E se você tentar se DateCreated
conformar com UTC porque julianday('now')
vai contra uma data GMT:
SELECT julianday('now') - julianday(DateCreated, 'utc') FROM Payment;
Isso tem um bug que adiciona uma hora para um DateCreated
que é durante o horário de verão (março-novembro). Digamos que "agora" seja ao meio-dia em um dia diferente do horário de verão e você criou algo em junho (durante o horário de verão) ao meio-dia, seu resultado dará 1 hora de intervalo, em vez de 0 horas, para a parte das horas. Você teria que escrever uma função no código do seu aplicativo que está exibindo o resultado para modificar o resultado e subtrair uma hora das datas do horário de verão. Fiz isso, até perceber que havia uma solução melhor para aquele problema que estava tendo: SQLite vs. Oracle - Calculando diferenças de data - horas
Em vez disso, como foi apontado para mim, para datas armazenadas na hora local, faça com que ambas correspondam à hora local:
SELECT julianday('now', 'localtime') - julianday(DateCreated) FROM Payment;
Ou acrescente 'Z'
a hora local:
julianday(datetime('now', 'localtime')||'Z') - julianday(CREATED_DATE||'Z')
Ambos parecem compensar e não adicionar a hora extra para datas de horário de verão e fazer subtração direta - de modo que o item criado ao meio-dia em um dia de horário de verão, ao verificar ao meio-dia em um dia não horário de verão, não receberá uma hora extra quando realizar o cálculo.
E embora eu reconheça que a maioria dirá não armazene datas no horário local em seu banco de dados e armazene-as em UTC para que você não se depare com isso, bem, nem todo aplicativo tem um público mundial, e nem todo programador deseja para passar pela conversão de CADA data em seu sistema para UTC e vice-versa toda vez que eles fizerem um GET ou SET no banco de dados e tentar descobrir se algo é local ou em UTC.
Apenas uma nota para escrever funções de relógio. Para quem procura horas trabalhadas, uma alteração muito simples disso faz com que as horas mais os minutos sejam mostrados como uma porcentagem de 60, conforme a maioria das empresas de folha de pagamento deseja.
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 você quiser o horário no formato 00:00: Resolvi assim:
select strftime('%H:%M',CAST ((julianday(FinishTime) - julianday(StartTime)) AS REAL),'12:00') from something
Dado que o seu formato de data segue: "AAAA-MM-DD HH: MM: SS", se você precisar encontrar a diferença entre duas datas em número de meses:
(strftime('%m', date1) + 12*strftime('%Y', date1)) -
(strftime('%m', date2) + 12*strftime('%Y', date2))
Em primeiro lugar, não está claro qual é o seu formato de data. Já existe uma resposta envolvendo strftime("%s")
.
Eu gosto de expandir essa resposta.
O SQLite possui apenas as seguintes classes de armazenamento: NULL, INTEGER, REAL, TEXT ou BLOB. Para simplificar, vou assumir que as datas são REAIS contendo os segundos desde 01/01/1970. Aqui está um esquema de amostra para o qual colocarei os dados de amostra de "1º de dezembro de 2018":
CREATE TABLE Payment (DateCreated REAL);
INSERT INTO Payment VALUES (strftime("%s", "2018-12-01"));
Agora vamos calcular a diferença de data entre "1º de dezembro de 2018" e agora (enquanto escrevo isso, é meio-dia de 12 de dezembro de 2018):
Diferença de data em dias:
SELECT (strftime("%s", "now") - DateCreated) / 86400.0 FROM Payment;
-- Output: 11.066875
Diferença de data em horas:
SELECT (strftime("%s", "now") - DateCreated) / 3600.0 FROM Payment;
-- Output: 265.606388888889
Diferença de data em minutos:
SELECT (strftime("%s", "now") - DateCreated) / 60.0 FROM Payment;
-- Output: 15936.4833333333
Diferença de data em segundos:
SELECT (strftime("%s", "now") - DateCreated) FROM Payment;
-- Output: 956195.0
Se você quiser registros entre dias,
select count(col_Name) from dataset where cast(julianday("now")- julianday(_Last_updated) as int)<=0;
No meu caso, tenho que calcular a diferença em minutos e julianday()
não dou um valor preciso. Em vez disso, eu uso strftime()
:
SELECT (strftime('%s', [UserEnd]) - strftime('%s', [UserStart])) / 60
Ambas as datas são convertidas em unixtime (segundos) e, em seguida, subtraídas para obter o valor em segundos entre as duas datas. Em seguida, divida por 60.