Howard Hinnant's civil_from_days algorithm. Converts a day count since the Unix epoch (1970-01-01) to a `YYYY-MM-DD` string.
(z: u64)
| 60 | /// Howard Hinnant's civil_from_days algorithm. |
| 61 | /// Converts a day count since the Unix epoch (1970-01-01) to a `YYYY-MM-DD` string. |
| 62 | fn civil_from_days(z: u64) -> String { |
| 63 | // Shift epoch from 1970-01-01 to 0000-03-01 for the algorithm. |
| 64 | let z = z as i64 + 719_468; |
| 65 | let era = if z >= 0 { z } else { z - 146_096 } / 146_097; |
| 66 | let doe = z - era * 146_097; // day of era [0, 146096] |
| 67 | let yoe = (doe - doe / 1460 + doe / 36524 - doe / 146_096) / 365; // year of era [0, 399] |
| 68 | let y = yoe + era * 400; |
| 69 | let doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // day of year [0, 365] |
| 70 | let mp = (5 * doy + 2) / 153; // month prime [0, 11] |
| 71 | let d = doy - (153 * mp + 2) / 5 + 1; // day [1, 31] |
| 72 | let m = if mp < 10 { mp + 3 } else { mp - 9 }; // month [1, 12] |
| 73 | let y = if m <= 2 { y + 1 } else { y }; |
| 74 | |
| 75 | format!("{:04}-{:02}-{:02}", y, m, d) |
| 76 | } |