SQLite:如何计算出生日期的年龄

时间:2010-06-26 13:02:09

标签: sqlite date

从sqlite3的出生日期开始计算年龄的最佳方法是什么?

8 个答案:

答案 0 :(得分:13)

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

答案 1 :(得分:11)

您可以将日期转换为浮点数并减去...

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

...其中doba valid SQLite time string

答案 2 :(得分:4)

只是为了澄清kai's answer(似乎编辑现在非常不受欢迎,评论有严格的大小限制和格式问题):

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) [“案例 A ”]
  • 0 否则[“案例 B ”];

(我假设sqlite对两个日期字符串进行了字典比较,并返回一个整数值。)

对于任何其他日历年,它将是当前第二之间的年数 - 即strftime('%Y', 'now') - strftime('%Y', Birth_Date) - 1,加上上述相同

换句话说,我们strftime('%Y', 'now') - strftime('%Y', Birth_Date)中减去 1 只有当 相反 “发生 - 即,当且仅当strftime('%m-%d', 'now') < strftime('%m-%d', Birth_Date),因此公式。

答案 3 :(得分:1)

我发现这可能会对你有帮助:

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

答案 4 :(得分:0)

要获得@Bruno Costa的工作答案,我必须在第4行的strftime差异计算周围添加括号,然后将比较反转到&#39; now&#39;小于或等于:据我所知,计算的是计算日期是在今天之前还是之后。如果计算的日期是今天或更早,那么生日已经是今年或今天:

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的答案相关联的解决方案尚未经过测试。

答案 5 :(得分:0)

另一个解决方案是将年份%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));

我更新了计算,因此它使用正确的十进制天数,如Robert在下面的评论中所述。

与其他计算的不同之处在于,此计算的结果是十进制数,可以转换为整数(以获得确切的年数)或舍入(以获得大致的年数)。

对于生日来说,大概的年数可能不相关,但是对于你购买的东西的年龄更有意义。

答案 6 :(得分:0)

我整个周末都在这个主题上,并创建了此查询。

SELECT ID,
       Name,
       InitialDate,
       LastDate,
       CASE 
           WHEN strftime('%m', LastDate) > strftime('%m', InitialDate) THEN strftime('%Y', LastDate) - strftime('%Y', InitialDate) 
           WHEN strftime('%m', LastDate) < strftime('%m', InitialDate) THEN strftime('%Y', LastDate) - strftime('%Y', InitialDate) - 1 
           WHEN strftime('%m', LastDate) = strftime('%m', InitialDate) THEN 
           CASE 
               WHEN strftime('%d', LastDate) >= strftime('%d', InitialDate) THEN strftime('%Y', LastDate) - strftime('%Y', InitialDate) 
               ELSE strftime('%Y', LastDate) - strftime('%Y', InitialDate) - 1 
           END 
       END AS Years,
       CASE
           WHEN strftime('%m', LastDate) == strftime('%m', InitialDate) THEN
               CASE
                   WHEN strftime('%d', LastDate) == strftime('%d', InitialDate)    THEN ( strftime('%m', LastDate) - strftime('%m', InitialDate) ) -- i.e., 0
                   WHEN strftime('%d', LastDate) > strftime('%d', InitialDate)     THEN ( strftime('%m', LastDate) - strftime('%m', InitialDate) ) -- i.e., 12
                   WHEN strftime('%d', InitialDate) > strftime('%d', LastDate)     THEN (strftime('%m', LastDate) - strftime('%m', InitialDate)) + 11 -- i.e., 11
               END
           WHEN strftime('%m', LastDate) > strftime('%m', InitialDate) THEN 
               CASE
                   WHEN strftime('%d', LastDate) == strftime('%d', InitialDate)    THEN strftime('%m', LastDate) - strftime('%m', InitialDate)
                   WHEN strftime('%d', LastDate) > strftime('%d', InitialDate)     THEN strftime('%m', LastDate) - strftime('%m', InitialDate)
                   WHEN strftime('%d', InitialDate) > strftime('%d', LastDate)     THEN ( strftime('%m', LastDate) - strftime('%m', InitialDate) ) - 1
               END
           WHEN strftime('%m', InitialDate) > strftime('%m', LastDate) THEN
               CASE 
                   WHEN strftime('%d', LastDate) == strftime('%d', InitialDate)    THEN 12 - ( strftime('%m', InitialDate) - strftime('%m', LastDate) )
                   WHEN strftime('%d', LastDate) > strftime('%d', InitialDate)     THEN 12 - ( strftime('%m', InitialDate) - strftime('%m', LastDate) )
                   WHEN strftime('%d', InitialDate) > strftime('%d', LastDate)     THEN 11 - (strftime('%m', InitialDate) - strftime('%m', LastDate))
               END           
       END AS Months,
       CASE 
           WHEN strftime('%d', LastDate) == strftime('%d', InitialDate)    THEN 0
           WHEN strftime('%d', LastDate) > strftime('%d', InitialDate)     THEN strftime('%d', LastDate) - strftime('%d', InitialDate)
           WHEN strftime('%d', InitialDate) > strftime('%d', LastDate)     THEN ( strftime('%d', date(InitialDate, 'start of month', '+1 month', '-1 day') ) - strftime('%d', InitialDate) + strftime('%d', LastDate) )
            
   END AS Days
  FROM tbl_Dates;

在包含248条记录的数据集上进行了测试。年和月的计算精度为100%。天数是248条记录中的124条,其差值为±1天。我将要求其他Genius Minds进行挖掘并找到剩余的解决方案。对我来说还可以,并且可以100%正常工作。

答案 7 :(得分:-1)

在sqllite中做IT非常困难...所以你最好从数据库nd中检索出生日期然后添加这个逻辑

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();

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

“candidateAge”将具有年龄。