вы можете перегрузить методы convert
и создать пользовательский тип, содержащий значение.
using Dates
struct ExcelDate{T<:Real}
val::T
end
function exceldatetodate(exceldate::Integer)
Dates.DateTime(1899, 12, 30) + Dates.Day(exceldate)
end
function exceldatetodate(exceldate::Real)
t,d = modf(exceldate)
return Dates.DateTime(1899, 12, 30) + Dates.Day(d) + Dates.Millisecond((floor(t * 86400000)))
end
function exceldatetodate(exceldate::ExcelDate)
exceldatetodate(exceldate.val)
end
function exceldatetodate(exceldate::ExcelDate)
exceldatetodate(exceldate.val)
end
function toexceldate(date::Date)
datetime = Dates.value(DateTime(date) - Dates.DateTime(1899, 12, 30))
datetime = round(datetime/86400000,digits = 3)
return ExcelDate(datetime)
end
function toexceldate(date::DateTime)
datetime = Dates.value(date - Dates.DateTime(1899, 12, 30))
datetime = round(datetime/86400000,digits = 3)
return ExcelDate(datetime)
end
Base.convert(d::Type{Dates.DateTime},n::ExcelDate) = exceldatetodate(n)
Base.convert(d::Type{Dates.Date},n::ExcelDate) = convert(Date,exceldatetodate(n))
Base.convert(d::Type{T},n::ExcelDate) where T<: Real = convert(d,n.val)
Base.convert(d::Type{ExcelDate},n::Dates.DateTime) = toexceldate(n)
Base.convert(d::Type{ExcelDate},n::Dates.Date) = toexceldate(n)
затем вы можете поиграть со значениями:
original_numbers = 40000.01:41000.01 #test numbers
excel_dates = convert.(ExcelDate,original_numbers)
dates = convert.(Date,excel_dates) #just days
datetimes = convert.(DateTime,excel_dates) #days and miliseconds
orig2 = convert.(ExcelDate,datetimes) #this preserves the original number
orig3 = convert.(ExcelDate,dates) #this does not preserve the original number
IsОчень важно отметить, что в Excel все числа обрабатываются как float64, а в Julia Dates - это совершенно другой тип.На мой взгляд, если вы хотите, чтобы определенный диапазон чисел вел себя как дата, лучше создать тип, отражающий это поведение.Одной из важных характеристик даты Excel является то, что вы можете оперировать датами, например числами, но результат этой операции не форматируется как дата.Это является результатом решения Excel об использовании Float64 для представления дат.Определенный тип имеет больше ограничений, чем число, и если вы хотите работать с датами в виде чисел, вы можете сначала преобразовать ExcelDate
в числа, но имеет смысл просто использовать тип julia Date
,у него есть лучшие и более эффективные методы для использования с датами.
Оффтопик, но даты - это нерешенная проблема программирования с разными стандартами для всех языков программирования.