Date to float

Is there an easy way to convert date/datetime to a float representing year? I.e. f(2000-01-01) = 2000, f(2015-07-01) ~ 2015.5 and so on. The most obvious method is 2000 + (x - DateTime(2000, 1, 1)) / (DateTime(2001, 1, 1) - DateTime(2000, 1, 1)), but it is only approximate, of course, and becomes more and more wrong for dates far from the reference point (2000 in this case).

1 Like

I sometimes (in PyPlot surface plots) use this:

(y,m,d) = (Dates.year.(dN),Dates.month.(dN),Dates.day.(dN))
DaysInMonth   = Dates.daysinmonth.(dN)         
RelDayInMonth = (d.-1)./DaysInMonth              
utDatum       = y + (m.-1)/12 + RelDayInMonth*1/12
const DTM = Union{Date, DateTime}
# assuming you want 2000-01-01 to become 2000.0
yfrac(dtm::DTM) = (dayofyear(dtm) - 1) / daysinyear(dtm)
decimaldate(dtm::DTM) = year(dtm) + yfrac(dtm)

CAUTION: decimaldate is inexact.

Thanks, this looks like exactly what I need! What do you mean by inexact?

Using floating point values rather than rational values to represent a wide swath of highly resolved times is inherently inexact.

1 Like

You are representing a real number using a binary floating point representation

Binary floating point representation cannot even represent 0.1 (aka 1/10) exactly!!!

julia> 0.1 + 0.1 + 0.1
0.30000000000000004

"using Precision Decimal Floating Point module (not avail to public)"
julia> using PDFPs

julia> PDFP_setDefaultPrecision(4)
4

julia> PDFP("0.1") + PDFP("0.1") + PDFP("0.1")
PDFP(0, -1, [3, 0, 0, 0])

julia> PDFP_toCommonString(ans)
"0.3000"

julia> PDFP_toExplainationString( PDFP("0.1") + PDFP("0.1") + PDFP("0.1") )
"+1 * 3.000 * 10^-1"

Sure, but it is inherent to all float values, and not related to conversion from date.

In case anyone encounters this thread looking for a solution.
I published a package Alexander Plavin / DateFormats.jl · GitLab (registered in General) earlier this year. It converts Dates and DateTimes to/from a range of formats, including decimal year (e.g. 2021.45). The implemented conversion is more accurate than the one posted above.

6 Likes