# Time difference in months/quarters/years

I’d like to calculate the number of periods between two dates. The aim is to calculate a loan amortizing schedule.

The following code arrives up to a certain point, i.e. to calculate the interval in days, but I’d like to convert those days in month, quarters or years as applicable. I’d use yearfrac and multiply it by a factor but I don’t find it easy to vectorize it.

``````using Dates, DayCounts
start_date = [Date(2022, 1, 1), Date(2021, 1, 1)]
maturity_date = [Date(2023, 1, 1), Date(2022, 12, 1)]
time_period = (Dates.value.(maturity_date) .- Dates.value.(start_date))

# or

time_period = yearfrac(start_date[1,1], maturity_date[1,1], DayCounts.Thirty360())
``````

You can use `Ref` to treat values as scalars and exclude them from broadcast:

``````julia> time_period = yearfrac.(start_date, maturity_date, Ref(DayCounts.Thirty360()))
2-element Vector{Float64}:
1.0
1.9166666666666667
``````
1 Like

@contradict has already provided you with a way to vectorize `yearfrac`.

An alternative is to compute the time difference in `Day`s, as you did, and divide it by the period in `Day`s:

``````julia> using Dates
julia> start_date = [Date(2022, 1, 1), Date(2021, 1, 1)];
julia> maturity_date = [Date(2023, 1, 1), Date(2022, 12, 1)];
julia> days_between = maturity_date .- start_date;
julia> months_between = days_between ./ Day(30)
2-element Vector{Float64}:
12.166666666666666
23.3
``````

However, this way, you have to be precise about what you mean by a “period”, and take care of the rounding. For example, notice that the “number of months” (`Day(30)`) in a “year” (`Day(365)`) is not 12 this way.

Another way is to use ranges as proposed in https://discourse.julialang.org/t/number-of-months-between-two-dates/42128/3:

``````julia> [length(s:period:e) for (s, e) in zip(start_date, maturity_date)]
2-element Vector{Int64}:
13
24
``````

But ranges are inclusive in julia, so for example:

``````julia> collect(Date(2022, 1, 1):Month(1):Date(2023, 1, 1))
13-element Vector{Date}:
2022-01-01
2022-02-01
2022-03-01
2022-04-01
2022-05-01
2022-06-01
2022-07-01
2022-08-01
2022-09-01
2022-10-01
2022-11-01
2022-12-01
2023-01-01 # this is the maturity date
``````

so you might want to subtract a `Day(1)` from the maturity dates.

Both are good answers, for the task of amortizing a pool of loans I ended up using this solution to avoid having to round yearfrac

``````n_periods = [length(s:Month((12/p)):e) for (s, p, e) in zip(start_date, frequency,maturity_date)].-1

``````