SQLite: Как рассчитать возраст от даты рождения - PullRequest
10 голосов
/ 26 июня 2010

Как лучше всего рассчитать возраст в годах от даты рождения в sqlite3?

Ответы [ 7 ]

13 голосов
/ 26 июня 2010
SELECT (strftime('%Y', 'now') - strftime('%Y', Birth_Date)) - (strftime('%m-%d', 'now') < strftime('%m-%d', Birth_Date));

Этот работает.
Я просто портировал этот пример MySQL: http://dev.mysql.com/doc/refman/5.0/en/date-calculations.html

11 голосов
/ 06 июля 2013

Вы можете преобразовать даты в числа с плавающей запятой и вычесть…

cast(strftime('%Y.%m%d', 'now') - strftime('%Y.%m%d', dob) as int)

… где dob равно допустимая строка времени SQLite .

4 голосов
/ 30 мая 2013

Просто чтобы уточнить ответ Кая (кажется, что редактирование сейчас очень нежелательно, а комментарии имеют сильные ограничения по размеру и форматированию):

SELECT (strftime('%Y', 'now') - strftime('%Y', Birth_Date)) 
     - (strftime('%m-%d', 'now') < strftime('%m-%d', Birth_Date) );

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

Для второго календарного года это будет зависеть от даты - т.е. это будет:

  • 1 для strftime('%m-%d', 'now') >= strftime('%m-%d', Birth_Date) ["case A "]
  • и 0 в противном случае ["case B "];

(я предполагаю, что sqlite выполняет лексикографическое сравнение двух строк дат и возвращает целочисленное значение.)

Для любого другого календарного года это будет число лет между текущий и второй - то есть strftime('%Y', 'now') - strftime('%Y', Birth_Date) - 1, плюс то же, что и выше.

Другими словами, мы вычитаем 1 с strftime('%Y', 'now') - strftime('%Y', Birth_Date) только если напротив"case A " происходит - то есть, если и только если strftime('%m-%d', 'now') < strftime('%m-%d', Birth_Date), отсюда формула.

1 голос
/ 26 июня 2010

Я нашел это, которое, возможно, поможет вам:

select
    case
        when date(dob, '+' ||
            strftime('%Y', 'now') - strftime('%Y', dob) ||
            ' years') >= date('now')
        then strftime('%Y', 'now') - strftime('%Y', dob)
        else strftime('%Y', 'now') - strftime('%Y', dob) - 1
    end
    as age
from t;

С http://www.mail-archive.com/sqlite-users@sqlite.org/msg20525.html

0 голосов
/ 28 февраля 2018

Другое решение состоит в том, чтобы использовать день года %j как часть года, разделив его на 365,0.Таким образом, вы получите:

select strftime('%Y', 'now') + strftime('%j', 'now') / 365.2422) - (strftime('%Y', Birth_Date) + strftime('%j', Birth_Date) / 365.2422);

Затем вы можете привести результат к целому числу:

select CAST(strftime('%Y', 'now') + strftime('%j', 'now') / 365.2422) - (strftime('%Y', Birth_Date) + strftime('%j', Birth_Date) / 365.2422) AS INT);

или использовать ROUND () для округления результата:

select round(strftime('%Y', 'now') + strftime('%j', 'now') / 365.2422) - (strftime('%Y', Birth_Date) + strftime('%j', Birth_Date) / 365.2422));

Я обновил расчет, чтобы он использовал правильное десятичное число дней в солнечном году, как отметил Роберт в комментарии ниже.

Разница с другими расчетами заключается в том, что результат этого вычислениядесятичное число, которое может быть приведено к целому числу (чтобы получить точное количество лет) или округленному (чтобы получить приблизительное количество лет).

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

0 голосов
/ 17 февраля 2013

Чтобы получить ответ @Bruno Costa на работу, мне пришлось добавить квадратные скобки вокруг вычисления разности strftime в 4-й строке и повернуть сравнение до «сейчас», чтобы оно было меньше или равно: насколько я понимаю, вычисление работает ли расчетная дата до или после сегодняшнего дня. Если расчетная дата сегодня или раньше, то день рождения уже был в этом году или сегодня:

select
    case
        when date(dob, '+' ||
            (strftime('%Y', 'now') - strftime('%Y', dob)) ||
            ' years') <= date('now')
        then strftime('%Y', 'now') - strftime('%Y', dob)
        else strftime('%Y', 'now') - strftime('%Y', dob) - 1
    end
    as age
from t;

Обратите внимание, что решение, на которое ссылается ответ @Bruno Costa, не было проверено.

0 голосов
/ 27 апреля 2012

Это очень трудно сделать в sqllite ... так что лучше взять дату рождения из базы данных и добавить эту логику

private Calendar mConvert_Date_To_Calendar(String dateToConvert)
{
    // TODO Auto-generated method stub
    try
    {
        Calendar calConversion = Calendar.getInstance();
        Date date1 = null;
        try
        {
            date1 = new SimpleDateFormat("dd/MM/yy").parse(dateToConvert);
        }
        catch (ParseException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        calConversion.setTime(date1);
        System.out.println("mConvert_Date_To_Calender date1: " + date1
                + "caleder converted done:" + calConversion.getTime());
        return calConversion;
    }
    catch (Exception e)
    {
        e.printStackTrace();
        Log.i(TAG, "" + e);
        return null;
    }
}


private Calendar myCurrentCalender()
{
    try
    {
        Calendar myCurrentCal = Calendar.getInstance();
        myCurrentCal.set(myCurrentCal.get(Calendar.YEAR), myCurrentCal.get(Calendar.MONTH),
                myCurrentCal.get(Calendar.DAY_OF_MONTH));
        return myCurrentCal;
    }
    catch (Exception e)
    {
        e.printStackTrace();
        Log.e(TAG, "Unable to get current calendar!");
        return null;
    }
}

public int daysBetween(Date d1, Date d2)
{
    System.out.println("calculated age :"
            + (((d2.getTime() - d1.getTime()) / ((24 * 1000 * 60 * 60)) / 365)));

    return (int) (((d2.getTime() - d1.getTime()) / (24 * 1000 * 60 * 60)) / 365);
}

Первая функция рассчитает дату рождения в календарном формате, вторая - текущую дату, третья - разницу между ними. Эти функции должны вызываться, как показано ниже

dateOfBirth = mConvert_Date_To_Calendar (age);

currentDate = myCurrentCalender ();

candidAge = daysBetween (dateOfBirth.getTime (), currentDate.getTime ());

«Кандидат в возрасте» будет иметь возраст.

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