Разница между двумя датами в SQLite

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

SELECT Date('now') - DateCreated FROM Payment 

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

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

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

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

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

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

 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) 

SQLite wiki – отличная ссылка, а страница 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; 

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

Если ваши даты хранятся в местное время, использование вышеуказанного кода сделает ваш ответ WRONG на количество часов вашего смещения по GMT. Если вы находитесь в восточных штатах, таких как я, то есть GMT-5, ваш результат будет содержать 5 часов. И если вы попытаетесь сделать DateCreated совместимым с UTC, потому что julianday('now') идет против даты GMT:

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

У этого есть ошибка, где он добавит час для DateCreated который находится во время летнего времени (март-ноябрь). Скажите, что «сейчас» в полдень в день, не относящийся к DST, и вы создали что-то еще в июне (во время DST) в полдень, ваш результат даст 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 

Если вам нужны записи между днями,

 select count(col_Name) from dataset where cast(julianday("now")- julianday(_Last_updated) as int)<=0; 

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

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

  • Ошибка приложения при запуске из-за java.lang.IllegalArgumentException: column '_id' не существует
  • Как конкатенировать строки с заполнением в sqlite
  • Как просмотреть данные, сохраненные в базе данных Android (SQLite)?
  • Поддерживает ли Android поддержку JDBC
  • Android - вытащить Android-устройство SQlite
  • Пароль Защитите SQLite DB. Является ли это возможным?
  • Core Data и SQLite для опытных разработчиков SQL
  • Операция «Вставить, если не существует» в SQLite
  • Запрос LIMIT / OFFSET Sqlite
  • Отладка базы данных sqlite на устройстве
  • SQLite UPSERT / UPDATE ИЛИ INSERT
  • Давайте будем гением компьютера.