let create ?(zone = 0) time =
let time = time +. float_of_int (zone * 60) in
let days = floor (time /. 86400.0) in
let in_day = int_of_float (time -. 86400.0 *. days) in
let days = days +. 719528.0 in
let n400 = floor (days /. 146097.0) in
let r400 = int_of_float (days -. n400 *. 146097.0) in
let n400 = int_of_float n400 in
let (n100, r100) =
if r400 < 36525 then 0, r400 else (r400 - 1) / 36524, (r400 - 1) mod 36524
in
let (n4, r4) =
if n100 = 0 then r100 / 1461, r100 mod 1461
else if r100 < 1460 then 0, r100
else (r100 + 1) / 1461, (r100 + 1) mod 1461
in
let (n1, r1) =
if n4 = 0 && n100 <> 0 then r4 / 365, r4 mod 365
else if r4 < 366 then 0, r4
else (r4 - 1) / 365, (r4 - 1) mod 365
in
let year = 400 * n400 + 100 * n100 + 4 * n4 + n1 in
let month_start =
if is_leap year then fun m -> months_start.(m) + (if m > 1 then 1 else 0)
else fun m -> months_start.(m)
in
let month_guess = r1 / 29 in
let month =
if month_guess = 12 then 11
else if r1 >= month_start month_guess then month_guess
else month_guess - 1
in
let second = in_day mod 60
and minutes = in_day / 60 in
let minute = minutes mod 60
and hour = minutes / 60 in
{year = year; month = month + 1; day = r1 - month_start month + 1;
hour = hour; minute = minute; second = second; zone = zone;
week_day = int_of_float (mod_float (days +. 6.0) 7.0)}