Разница между двумя датами в SQLite - PullRequest
86 голосов
/ 14 ноября 2008

Как узнать разницу в днях между двумя датами в SQLite? Я уже пробовал что-то вроде этого:

SELECT Date('now') - DateCreated FROM Payment

Возвращает 0 каждый раз.

Ответы [ 11 ]

102 голосов
/ 14 ноября 2008
 SELECT julianday('now') - julianday(DateCreated) FROM Payment;
39 голосов
/ 20 декабря 2015

Разница в днях

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)
31 голосов
/ 09 февраля 2013

Оба ответа обеспечивают более сложные решения, так как они нужно быть. Скажем, платеж был создан на January 6, 2013. И мы хотим знать разницу между этой датой и сегодняшним днем.

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

Разница составляет 34 дня. Мы можем использовать julianday('now') для лучшая ясность Другими словами, нам не нужно ставить date() или datetime() действуют как параметры для julianday() функция.

20 голосов
/ 17 ноября 2008

Вики-сайт SQLite является отличным справочником, а страницу DateAndTimeFunctions можно добавить в закладки. Также полезно помнить, что с запросами командной строки sqlite играть довольно просто:

sqlite> select julianday(datetime('now'));
2454788.09219907
sqlite> select datetime(julianday(datetime('now')));
2008-11-17 14:13:55
4 голосов
/ 08 декабря 2016

Этот ответ немного запутан, и документация не скажет вам этого (поскольку они предполагают, что вы храните ваши даты как даты UTC в базе данных), но ответ на этот вопрос во многом зависит от часового пояса, в котором вы находитесь. даты хранятся в. Вы также не используете Date('now'), но используете функцию julianday(), чтобы вычислить обе даты в сравнении с общей датой, а затем вычесть разницу между этими результатами.

Если ваши даты хранятся в UTC:

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

Это ответ высшего ранга, а также документация . Это только часть картины и очень упрощенный ответ, если вы спросите меня.

Если ваши даты хранятся по местному времени, с помощью приведенного выше кода ваш ответ сделает НЕПРАВИЛЬНЫМ на количество часов, в которое смещено ваше GMT. Если вы находитесь в восточной части США, как я, то есть по Гринвичу -5, ваш результат будет добавлен на 5 часов. И если вы попытаетесь заставить DateCreated соответствовать UTC, потому что julianday('now') идет против даты по Гринвичу:

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

Имеется ошибка, из-за которой добавляется час для DateCreated в летнее время (март-ноябрь). Скажем, что «сейчас» в полдень не в день перехода на летнее время, и вы создали что-то еще в июне (во время летнего времени) в полдень, ваш результат будет давать 1 час, а не 0 часов, для части часов. Вам нужно написать функцию в коде вашего приложения, которая отображает результат, чтобы изменить результат и вычесть час из дат летнего времени. Я делал это, пока не понял, что у меня есть лучшее решение этой проблемы: SQLite против Oracle - Расчет разницы дат - часы

Вместо этого, как мне было указано, для дат, хранящихся по местному времени, сопоставьте оба значения с местным временем:

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

Или добавить 'Z' к местному времени:

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

Оба из них, похоже, компенсируют и не добавляют дополнительный час для дат летнего времени и производят прямое вычитание - так, чтобы элемент, созданный в полдень в день летнего времени, при проверке в полдень не в день летнего времени, не получал дополнительный час при выполнении расчета.

И хотя я признаю, что большинство из них скажут: не храните даты в местном времени в вашей базе данных, а сохраняйте их в UTC, чтобы вы не столкнулись с этим, но не у каждого приложения есть всемирная аудитория, и не каждый программист хочет выполнить преобразование КАЖДОЙ даты в своей системе в UTC и обратно каждый раз, когда он выполняет GET или SET в базе данных и пытается выяснить, является ли что-то локальным или в UTC.

2 голосов
/ 22 марта 2017

Если вы хотите время в формате 00:00: Я решил это так:

select strftime('%H:%M',CAST ((julianday(FinishTime) - julianday(StartTime)) AS REAL),'12:00') from something
2 голосов
/ 11 августа 2016

Просто примечание для написания функций таймера. Для тех, кто ищет отработанные часы, очень простое изменение показывает, что часы плюс минуты показываются в процентах от 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
0 голосов
/ 12 декабря 2018

Во-первых, не ясно, какой у вас формат даты. Уже есть ответ, включающий strftime("%s").

Мне нравится расширять этот ответ.

SQLite имеет только следующие классы хранения: NULL, INTEGER, REAL, TEXT или BLOB. Чтобы упростить вещи, я собираюсь предположить, что даты НАСТОЯЩИЕ содержат секунды с 1970-01-01. Вот пример схемы, для которой я добавлю пример данных «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
0 голосов
/ 28 ноября 2018

В моем случае я должен рассчитать разницу в минутах, а julianday() не дает точного значения. Вместо этого я использую strftime():

SELECT strftime('%s', [UserEnd]) - strftime('%s', [UserStart])) / 60

Обе даты конвертируются в unixtime (секунды), затем вычитаются, чтобы получить значение в секундах между двумя датами. Затем разделите его на 60.

https://www.sqlite.org/cvstrac/wiki?p=DateAndTimeFunctions

0 голосов
/ 15 апреля 2018

Учитывая, что ваш формат даты следующий: "ГГГГ-ММ-ДД ЧЧ: ММ: СС", если вам нужно найти разницу между двумя датами в количестве месяцев:

(strftime('%m', date1) + 12*strftime('%Y', date1)) - (strftime('%m', date2) + 12*strftime('%Y', date2))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...