Как узнать разницу в днях между двумя датами в SQLite? Я уже пробовал что-то подобное:
SELECT Date('now') - DateCreated FROM Payment
Он каждый раз возвращает 0.
Как узнать разницу в днях между двумя датами в SQLite? Я уже пробовал что-то подобное:
SELECT Date('now') - DateCreated FROM Payment
Он каждый раз возвращает 0.
Ответы:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
DateCreated
находитесь в UTC. Если вместо этого используется местное время, вам необходимо преобразовать его julianday('now')
в местное время. Я не мог найти нигде, где была бы эта информация. Если вам julianday('now') - julianday(DateCreated)
нравится, что этот пост предлагает дату, хранящуюся в местном времени, ваш ответ будет отклонен от вашего смещения от GMT и будет неправильным. Хотя, возможно, это не лучшая практика для хранения дат по местному времени, это все же может происходить в приложениях, где часовые пояса не имеют значения (кроме случаев, когда инструмент, с которым вы работаете, навязывает их вам, как здесь).
julianday('now') - julianday(DateCreated, 'utc')
, чтобы сделать оба UTC, это не будет работать так же, как это julianday('now', 'localtime') - julianday(DateCreated)
. Первый не учитывает дни летнего времени и добавит дополнительный час к созданным датам в марте-ноябре. Последнее действительно объясняет это. stackoverflow.com/questions/41007455/…
Разница в днях
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) As Integer)
Разница в часах
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 As Integer)
Разница в минутах
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 As Integer)
Разница в секундах
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 * 60 As Integer)
Оба ответа предлагают решения немного более сложные, как и должно быть. Допустим, платеж был создан January 6, 2013
. И мы хотим знать разницу между этой датой и сегодняшним днем.
sqlite> SELECT julianday() - julianday('2013-01-06');
34.7978485878557
Разница составляет 34 дня. Мы можем использовать julianday('now')
для большей ясности. Другими словами, нам не нужно указывать
date()
или datetime()
функции в качестве параметров для julianday()
работы.
Документация по SQLite - отличный справочник, а страницу DateAndTimeFunctions можно добавить в закладки.
Также полезно помнить, что довольно легко играть с запросами с помощью утилиты командной строки sqlite:
sqlite> select julianday(datetime('now'));
2454788.09219907
sqlite> select datetime(julianday(datetime('now')));
2008-11-17 14:13:55
Этот ответ немного длинен, и документация не скажет вам этого (потому что они предполагают, что вы храните свои даты как даты в формате UTC в базе данных), но ответ на этот вопрос во многом зависит от часового пояса, в котором хранятся ваши даты in. Вы также не используете Date('now')
, но используете эту julianday()
функцию, чтобы вычислить обе даты относительно общей даты, а затем вычесть разницу этих результатов друг с другом.
Если ваши даты хранятся в формате UTC:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
Это то, что есть в верхнем рейтинге ответа, а также в документации . Если вы спросите меня, это только часть картины и очень упрощенный ответ.
Если ваши даты хранятся в местном времени, использование приведенного выше кода сделает ваш ответ НЕПРАВИЛЬНЫМ по количеству часов, в которых указано смещение по Гринвичу. Если вы, как и я, находитесь в восточной части США, то есть по Гринвичу -5, к вашему результату будут добавлены 5 часов. И если вы попытаетесь DateCreated
согласоваться с UTC, потому что julianday('now')
это не соответствует дате GMT:
SELECT julianday('now') - julianday(DateCreated, 'utc') FROM Payment;
У этого есть ошибка, из-за которой он добавляет час для DateCreated
летнего времени (март-ноябрь). Предположим, что «сейчас» - это полдень в день, не относящийся к летнему времени, и вы создали что-то еще в июне (во время летнего времени) в полдень, ваш результат даст интервал в 1 час вместо 0 часов для части часов. Вам нужно будет написать функцию в коде вашего приложения, которая отображает результат, чтобы изменить результат и вычесть час из дат DST. Я делал это, пока не понял, что есть лучшее решение той проблемы, с которой я столкнулся: SQLite против Oracle - Расчет разницы в датах - часы
Вместо этого, как мне было указано, для дат, хранящихся в местном времени, сопоставьте оба с местным временем:
SELECT julianday('now', 'localtime') - julianday(DateCreated) FROM Payment;
Или добавьте 'Z'
к местному времени:
julianday(datetime('now', 'localtime')||'Z') - julianday(CREATED_DATE||'Z')
Оба из них, кажется, компенсируют и не добавляют дополнительный час для дат DST и выполняют прямое вычитание - так что элемент, созданный в полдень в день DST, при проверке в полдень в день без DST, не получит дополнительный час, когда выполнение расчета.
И хотя я понимаю, что большинство скажет, что не храните даты в локальном времени в своей базе данных и храните их в UTC, чтобы вы не столкнулись с этим, ну, не каждое приложение имеет всемирную аудиторию, и не каждый программист хочет чтобы выполнять преобразование КАЖДОЙ даты в своей системе в UTC и обратно каждый раз, когда они выполняют GET или SET в базе данных и пытаются выяснить, является ли что-то локальным или в UTC.
Просто примечание для написания функций таймера. Для тех, кто ищет количество отработанных часов, очень простое изменение этого параметра позволяет отображать часы плюс минуты в процентах от 60, как того требует большинство компаний по начислению заработной платы.
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: я решил это так:
select strftime('%H:%M',CAST ((julianday(FinishTime) - julianday(StartTime)) AS REAL),'12:00') from something
Во-первых, непонятно, какой у вас формат даты. Ответ уже есть strftime("%s")
.
Мне нравится расширять этот ответ.
SQLite имеет только следующие классы хранения: NULL, INTEGER, REAL, TEXT или BLOB. Чтобы упростить ситуацию, я предполагаю, что даты НАСТОЯЩИЕ и содержат секунды с 01.01.1970. Вот образец схемы, для которой я вставлю образец данных от «1 декабря 2018 года»:
CREATE TABLE Payment (DateCreated REAL);
INSERT INTO Payment VALUES (strftime("%s", "2018-12-01"));
Теперь давайте определим разницу в датах между «1 декабря 2018 года» и сейчас (когда я пишу это, это полдень 12 декабря 2018 года):
Разница дат в днях:
SELECT (strftime("%s", "now") - DateCreated) / 86400.0 FROM Payment;
-- Output: 11.066875
Разница дат в часах:
SELECT (strftime("%s", "now") - DateCreated) / 3600.0 FROM Payment;
-- Output: 265.606388888889
Разница дат в минутах:
SELECT (strftime("%s", "now") - DateCreated) / 60.0 FROM Payment;
-- Output: 15936.4833333333
Разница дат в секундах:
SELECT (strftime("%s", "now") - DateCreated) FROM Payment;
-- Output: 956195.0
Если вам нужна разница в секундах
SELECT strftime('%s', '2019-12-02 12:32:53') - strftime('%s', '2019-12-02 11:32:53')
Если вам нужны записи между днями,
select count(col_Name) from dataset where cast(julianday("now")- julianday(_Last_updated) as int)<=0;
В моем случае я должен рассчитывать разницу в минутах и julianday()
не даю точного значения. Вместо этого я использую strftime()
:
SELECT (strftime('%s', [UserEnd]) - strftime('%s', [UserStart])) / 60
Обе даты преобразуются в unixtime (секунды), затем вычитаются, чтобы получить значение в секундах между двумя датами. Затем разделите его на 60.