Julia/Dates : convert a timespan from "days" to "year" or "Float64" - date

I would like to convert a timespan from "days" to "year" or "Float64"
let be at timespan t:
t = Date("2000-02-04") - Date("1996-06-04")
However each following lines give me an error
t/365
Float64(t)
parse(Float64,t)
convert(Dates.Year, t)

You can get the value stored in t and divide it by 365
julia> Dates.value(t)/365
3.671232876712329
Note however that this assumes that each year is 365 days which is not true. For some scenarios a more elegant solution would be to count the years assuming that the date starts at some point, have a look at the example below:
julia> d0 = Date("2000-01-01")
2000-01-01
julia> d1 = d0 + t
2003-09-02
julia> year(d1)-year(d0), month(d1)-month(d0), day(d1) - day(d0)
(3, 8, 1)

Related

In Julia, how do I set DateFormat year for 19 meaning 2019?

I have dates that look like "17-JAN-19", "18-FEB-20". When I attempt to use the Dates package Date("17-JAN-19", "d-u-yy") I get reasonably 0019-01-17. I could do Date("17-JAN-19", "d-u-yy") + Year(2000) but that introduces the possibility of new errors (I was going to give the example of leap year but that generally works though there is the very rare error Date("29-FEB-00", "d-u-yy")+Year(1900)).
Is there a date format that embeds known information about century?
As mentioned in https://github.com/JuliaLang/julia/issues/30002 there are multiple heuristics for assigning the century to a date. I would recommend being explicit and handling it through a helper function.
const NOCENTURYDF = DateFormat("d-u-y")
"""
parse_date(obj::AbstractString,
breakpoint::Integer = year(now()) - 2000,
century::Integer = 20)
Parses date in according to DateFormat("d-u-y") after attaching century information.
If the year portion is greater that the current year,
it assumes it corresponds to the previous century.
"""
function parse_date(obj::AbstractString,
breakpoint::Integer = year(now()) - 2000,
century::Integer = 20)
# breakpoint = year(now()) - 2000
# century = year(now()) ÷ 100
#assert 0 ≤ breakpoint ≤ 99
yy = rpad(parse(Int, match(r"\d{2}$", obj).match), 2, '0')
Date(string(obj[1:7],
century - (parse(Int, yy) > breakpoint),
yy),
NOCENTURYDF)
end
parse_date("17-JAN-19")
parse_date("29-FEB-00")

How to convert 9 digit number into a particular date format?

I want to convert 9 digit number into a particular date format.
Example -
Number - 000007547 ===> Date - 2016/10/05
Number - 000007550 ===> Date - 2016/10/08
Number - 000007559 ===> Date - 2016/10/17
I already have this numbers and it's dates but I'm unable to find the logic behind that conversion. Is anyone aware of this 9 digit date-time format?
It seems that the number is a count of days.
Try this python script:
from datetime import date
d0 = date(1996, 2, 6)
d1 = date(2016, 10, 17)
delta = d1 - d0
print delta.days
To convert this format you can use this script:
from datetime import date,timedelta
d0 = date(1996, 2, 6)
d1 = date(2016, 10, 17)
delta = d0 + timedelta(days=7559)
print delta
Output: 2016-10-17
It is the timestamp.
A timestamp is encoded information, which indicates the date and time at which a particular event has occurred.
import datetime
value=1258094605
date_obj=datetime.date.fromtimestamp(value)
print(date_obj)

Formatting milliseconds into hh:mm:ss - extraneous hours added

I'm using momentJS to find the difference between two times and format to hh:mm:ss. Ver: "moment": "~2.10.6"
The problem I'm having is an extraneous 7 hours being added to a time whose difference is only 1 minute, 1 second.
var diff_ms = moment('2016-07-29 10:35:18').diff('2016-07-29 10:34:17');
61000
var diff = moment(diff_ms).format('hh mm ss')
"07 01 01"
Convert milliseconds to hours and minutes using Momentjs says to specify the time unit as milliseconds, moment.duration(x, 'milliseconds');, but since it's returning the correct minutes and seconds (01 01), it seems it's correctly defaulting to milliseconds.
I can do this the "un-momentJS" way:
var a = moment.duration(61000, 'milliseconds');
a: n {_milliseconds: 61000, _days: 0, _months: 0, _data: Object,
_locale: l}
var b = a.hours() + ':' + a.minutes() + ':' + a.seconds();
b: 0:1:1
But don't have an easy way of formatting this output to hh:mm:ss using string concatenation like this.

Convert string month to numeric

I have a variable period that contains a month as an abbreviated string (i.e. "JAN", "FEB", "MAR", etc). How do I convert period to a numeral (i.e. 1, 2, 3, etc)?
My solution is:
gen fake_date_s = "2000"+period+"1"
gen fake_date = date(fake_date_s, "YMD")
gen month = month(fake_date)
I don't think it's ugly:
clear
input ///
str3 period
JAN
FEB
DEC
end
list
gen monthnum = month(date("2000" + period + "1", "YMD"))
list
This also works:
gen monthnum = month(date(period, "M"))
as it sets the day and the year in the daily date to 01 and 1960, by default.
I'm sure you can find an alternative that doesn't use date functions, but why not use them?
Another approach is:
local i=1
foreach m in `c(Mons)' {
replace month = "`i'" if month == upper("`m'")
local ++i
}
destring month, replace

Compare dates in Lua

I have a variable with a date table that looks like this
* table:
[day]
* number: 15
[year]
* number: 2015
[month]
* number: 2
How do I get the days between the current date and the date above? Many thanks!
You can use os.time() to convert your table to seconds and get the current time and then use os.difftime() to compute the difference. see Lua Wiki for more details.
reference = os.time{day=15, year=2015, month=2}
daysfrom = os.difftime(os.time(), reference) / (24 * 60 * 60) -- seconds in a day
wholedays = math.floor(daysfrom)
print(wholedays) -- today it prints "1"
as #barnes53 pointed out could be off by one day for a few seconds so it's not ideal, but it may be good enough for your needs.
You can use the algorithms gathered here:
chrono-Compatible Low-Level Date Algorithms
The algorithms are shown using C++, but they can be easily implemented in Lua if you like, or you can implement them in C or C++ and then just provide Lua bindings.
The basic idea using these algorithms is to compute a day number for the two dates and then just subtract them to give you the number of days.
--[[
http://howardhinnant.github.io/date_algorithms.html
Returns number of days since civil 1970-01-01. Negative values indicate
days prior to 1970-01-01.
Preconditions: y-m-d represents a date in the civil (Gregorian) calendar
m is in [1, 12]
d is in [1, last_day_of_month(y, m)]
y is "approximately" in
[numeric_limits<Int>::min()/366, numeric_limits<Int>::max()/366]
Exact range of validity is:
[civil_from_days(numeric_limits<Int>::min()),
civil_from_days(numeric_limits<Int>::max()-719468)]
]]
function days_from_civil(y, m, d)
if m <= 2 then
y = y - 1
m = m + 9
else
m = m - 3
end
local era = math.floor(y/400)
local yoe = y - era * 400 -- [0, 399]
local doy = math.modf((153*m + 2)/5) + d-1 -- [0, 365]
local doe = yoe * 365 + math.modf(yoe/4) - math.modf(yoe/100) + doy -- [0, 146096]
return era * 146097 + doe - 719468
end
local reference_date = {year=2001, month = 1, day = 1}
local date = os.date("*t")
local reference_days = days_from_civil(reference_date.year, reference_date.month, reference_date.day)
local days = days_from_civil(date.year, date.month, date.day)
print(string.format("Today is %d days into the 21st century.",days-reference_days))
os.time (under Windows, at least) is limited to years from 1970 and up. If, for example, you need a general solution to also find ages in days for people born before 1970, this won't work. You can use a julian date conversion and subtract between the two numbers (today and your target date).
A sample julian date function that will work for practically any date AD is given below (Lua v5.3 because of // but you could adapt to earlier versions):
local
function div(n,d)
local a, b = 1, 1
if n < 0 then a = -1 end
if d < 0 then b = -1 end
return a * b * (math.abs(n) // math.abs(d))
end
--------------------------------------------------------------------------------
-- Convert a YYMMDD date to Julian since 1/1/1900 (negative answer possible)
--------------------------------------------------------------------------------
function julian(year, month, day)
local temp
if (year < 0) or (month < 1) or (month > 12)
or (day < 1) or (day > 31) then
return
end
temp = div(month - 14, 12)
return (
day - 32075 +
div(1461 * (year + 4800 + temp), 4) +
div(367 * (month - 2 - temp * 12), 12) -
div(3 * div(year + 4900 + temp, 100), 4)
) - 2415021
end