Issue when Converting object of Type day to year


I think I am having a bug when I want to convert number of days between 2 dates into years:
I have:
DateFinObservation = Dates.Date(2008,12,31)
DateNaiss = Dates.Date.(t.DateNaissance,“mm/dd/yyyy”)

test= DateFinObservation - DateNaissance #will give me number of days between 2 dates in type days
then if I want to make
test2=Dates.year(test) # I have error message MethodError : no method matching +(::Day,::Int64)

Can you please help?

What you were looking for is Dates.Year, but that does not work the way you want it either because a number of days cannot be converted into years as years have a variable number of days.

Two possible solutions are:

julia> Dates.year(d1) - Dates.year(d2)

julia> Dates.days(d1-d2)/365.25

PS: have a read through Please read: make it easier to help you.

I understand but:
Let’s say that NumDays = d1-d2 = 367 days
if I make Date.year (NumDays) I have an error message
if I make Date.year (367) i Have the right answer

As a scientific calculation I should be able to calculate datediff(d1,d2,yyyy) like we have in vba or R
Is that something that someone can work on the package Dates?

If you want the number of years as a fraction, there are many conventions in use: DayCounts.jl attempts to cover them all.

However it sounds like you want the largest integer n such that dt1 + Year(n) <= dt2, in which case you could do something like:

function nyears(dt1, dt2)
    n = div(dt2 - dt1, Day(365))
    dt1 + Year(n) <= dt2 ? n : n-1
julia> d1 = Dates.Date(2010,1,2)

julia> d2 = Dates.Date(2008,12,31)

julia> numdays = d1 - d2
367 days

julia> Dates.year(numdays)
ERROR: MethodError: no method matching +(::Day, ::Int64)

julia> Dates.year(Dates.value(numdays))

Note: This is not the same as DateDiff in VB (which only looks at the two years, not the months and days).


Note that Dates.year with an integer argument is undocumented: it effectively gives you the number of Rata Die years: see julia/accessors.jl at master · JuliaLang/julia · GitHub

1 Like

Thank you very much everyone. Actually Dates.values is very useful as well I tried a trick that works I did Dates.year(
Otherwise I coded a function that replicate Datediff from vba

Isn’t this just year(d1) - year(d2) ?

It is not the exact calculation of age as it should consider months and days

Note that you cannot calculate the age of a person in years when you know their age in days. So your function will need to work on both dates and not on their difference:

julia> function age(dob, date)
       age = Dates.year(date)- Dates.year(dob) -1
       if Dates.month(date)>Dates.month(dob) || (Dates.month(date)==Dates.month(dob) &&>
         age += 1
       return age

PS: have another read on how to quote your code: PSA: how to quote code with backticks


Some alternatives to the above age function…

Emphasis on performance, using yearmonthday:

function age2(dob, date)
    y,m,d = yearmonthday(date) .- yearmonthday(dob)
    y - (m > 0 || (m == 0 && d >= 0) ? 0 : 1)

Emphasis on brevity and simplicity (still faster than age):

function age3(dob, date)
    y = year(date) - year(dob)
    y - (dob > date - Year(y) ? 1 : 0)
For reference, here's the above `age` function
function age(dob, date)
    age = Dates.year(date)- Dates.year(dob) -1
    if Dates.month(date)>Dates.month(dob) || (Dates.month(date)==Dates.month(dob) &&>
        age += 1
    return age

Are they all the same?

range = Date(1996,1,1):Day(1):Date(2010,1,1)
for d1 = range, d2 = range
    age(d1, d2) ≡ age2(d1, d2) ≡ age3(d1, d2) || println(d1," ",d2)

Yes (no output generated). How do they perform?

julia> @btime [age(d1, d2) for d1=$range, d2=$range];
  1.675 s (2 allocations: 199.61 MiB)

julia> @btime [age2(d1, d2) for d1=$range, d2=$range];
  874.106 ms (2 allocations: 199.61 MiB)

julia> @btime [age3(d1, d2) for d1=$range, d2=$range];
  1.470 s (2 allocations: 199.61 MiB)