# Issue when Converting object of Type day to year

Hi,

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)

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)
9

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

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
end
``````
``````julia> d1 = Dates.Date(2010,1,2)
2010-01-02

julia> d2 = Dates.Date(2008,12,31)
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))
2
``````

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

2 Likes

Note that `Dates.year` with an integer argument is undocumented: it effectively gives you the number of Rata Die years: see https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/src/accessors.jl

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(Dates.day(startDate-EnDate))
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) &&  Dates.day(date)>=Dates.day(dob))
age += 1
end
return age
end
``````

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

3 Likes

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)
end
``````

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)
end
``````
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) &&  Dates.day(date)>=Dates.day(dob))
age += 1
end
return age
end
``````

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)
end
``````

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)
``````
2 Likes