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

szqfcxe2  于 2022-11-14  发布在  SQLite
关注(0)|答案(9)|浏览(310)

从SQLITE3中的出生日期计算年龄的最佳方法是什么?

jdgnovmf

jdgnovmf1#

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

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

…其中doba valid SQLite time string

9gm1akwq

9gm1akwq2#

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

lyr7nygr

lyr7nygr3#

只是为了澄清一下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**,只有当“caseA”的“相反”发生时--也就是,当且仅当strftime('%m-%d', 'now') < strftime('%m-%d', Birth_Date),也就是公式。

q43xntqr

q43xntqr4#

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

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%。而天数的计算存在±1天的差异问题(248条记录中的124条)。我会请求其他天才头脑挖掘并找到剩余的解决方案。对我来说,这是可以的,工作100%好。

x8diyxa7

x8diyxa75#

我找到了这个也许会对你有帮助:

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

zynd9foi

zynd9foi6#

我不得不为Microsoft SQL Server解决一个类似的问题,它没有适当的年龄函数。
对于许多应用程序,您需要从出生之日起计算完整的年数。例如,合法饮酒或驾驶年龄。在这些情况下,您要确保如果生日是今天或在今天之前,年份就算数,但如果生日是明天,就不算了。
在SQLite中,我有以下公式:

date(
    today,
    '-'||(strftime('%m',dob)-1)||' months',
    '-'||(strftime('%d',dob)-1)||' days'
) - dob AS age;

哪里

  • today为询问日期
  • dob为出生日期

假设日期是ISO8601格式的字符串(yyyy-mm-dd)。
其中的逻辑是:

  • date1 - date2只会发现年份的差异
  • 如果一年从生日开始,这就可以了,但可能不是这样
  • 根据生日和年初的差额调整要约日期

额外的-是为了补偿月份和天数从`开始,而不是从0开始。
您可以使用以下工具进行测试:

WITH dates AS (
    SELECT
        '2022-02-23' AS today,
        '1943-02-24' AS dob
)
SELECT
    date(
        today,
        '-'||(strftime('%m',dob)-1)||' months',
        '-'||(strftime('%d',dob)-1)||' days'
    )-dob AS age
FROM dates;

摆弄today的值来计算乔治·哈里森的年龄。

tyky79it

tyky79it7#

为了得到@Bruno Costa的工作答案,我不得不在第四行的strftime差计算中加上括号,并将比较反转到‘now’以小于或等于:据我所知,计算是计算出计算的日期是在今天之前还是之后。如果计算的日期是今天或更早,则生日已经是今年或今天:

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;

请注意,链接到in@bruno Costa的答案的解决方案未经测试。

7kjnsjlb

7kjnsjlb8#

另一种解决方案是将一年中的某一天%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));

我已经更新了计算,现在它使用了罗伯特在下面的评论中指出的太阳年中正确的十进制天数。
与其他计算的不同之处在于,这种计算的结果是一个十进制数字,可以转换为一个整数(以获得准确的年数)或四舍五入(以获得大致的年数)。
对于生日来说,大概的年限可能并不那么重要,但对于你买的东西的年龄来说,它更有意义。

wh6knrhe

wh6knrhe9#

在方晶石中很难做到这一点。因此,最好从数据库中检索出生日期,然后添加以下逻辑

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(年龄);
CurrentDate=myCurrentCalender();
CandiateAge=day sBetweet(ateOfBirth.getTime(),CurrentDate.getTime());
“候选人年龄”将会有这个年龄。

相关问题