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)}