I have a solution of a differential equations problem, with a given time vector, say 50 values in the range [0,10]. I want to use date along the abscissa axis in the plot. So essentially, I want to associate time 0 from the differential equation to, say, October 1, 2020, and so on.
Question: Is there a way to take a vector, say time = range(0,10,length=50) and add an initial date so that the result becomes a vector of dates?
Question: Would I have to interpolate the solution of the differential equation at integer times to achieve this?
Not clear enough, if you have 0 as Oct 1st, what would 0.20408 (second element in your time array) be, Oct 2nd? if so, then you only really care how long the time vector is:
This is not quite what I need. This would be pretending that the time step is 1 day, but it is not. Differential equation solvers typically use variable step length.
Still, your answer helps me if I interpolate the solution once a day.
It is possible that I need to use DateTime (??) to handle it properly. And – you have a point: I need to specify which time of day the clock starts.
function add_float2datetime(x,datetime)
d = Int(floor(x))
e = x-d
h = Int(floor(e*24))
e = e-h/24
m = Int(floor(e*24*60))
e = e-m/24/60
s = Int(floor(e*24*60*60))
e = e-s/24/60/60
ms = Int(floor(e*24*60*60*1e3))
return datetime+Day(d)+Hour(h)+Minute(m)+Second(s)+Millisecond(ms)
end
#
dt = DateTime(2020,10,1)
x = range(0,10,length=50)
#
add_float2datetime.(x,dt)
My function is not elegant… it could have been improved with test on argument types, and generalized in case x is something else than day.
Two other improvements…
I could have skipped the “add to” part, i.e., argument datetime if it had been possible to create a DateTime type with zero value for month… Maybe there is another way to do that.
Perhaps this function already exists? My second HP calculator, the HP-29c (produced in 1975; I bought it in 1979 or so), had functions → H.MS and ->H .
using Dates
import Dates: DateTime
function Dates.DateTime(x::Float64, origin = DateTime(0))
time = Millisecond(Int(floor(Millisecond(Day(1)).value * x)))
return origin + time
end
in other words: does your function definition constitute a modification/new method to the Dates package? [Probably not? By adding this function with name Dates.DateTime, it is only defined in the current session…??]
Yes. All now calls to Dates.DateTime can end up ambiguous because of that. This is the reason Type Piracy is not encouraged. If he added a new method using a a new type introduced by them, then there would be no risk of some code (loaded before this change and unaware of it) end up calling the new method when it was not wanted.
Addendum: @Skoffer did specifically import that function because if you get a function name by means of using you cannot add a new method to it, so as a safety net to avoid doing something disastrous without noticing.
Sorry for this confusion, I should have warn you that this is type piracy and it is not needed at all. You may use any other function name (like add_datetime) and it’ll work just fine.
On the other hand, it is not a first time I see request for constructing date time from float value, so I suppose it worth a PR to Dates or at least small separate package.
A design choice of timeperiod(x;...) is: should one allow the user to specify (i) the time unit of x (Day? Hour? etc.) and the accuracy (millisecond? second? etc.).