2 * Copyright (c) 2020 Tilman Sauerbeck (tilman at code-monkey de)
4 * Time::from_unix_time() adapted from musl's __secs_to_tm() which is
5 * Copyright © 2005-2020 Rich Felker, et al.
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 // 2000-03-01 (mod 400 year, immediately after feb29
39 const LEAPOCH: i32 = (946684800 + 86400 * (31 + 29));
41 const DAYS_PER_400Y: i32 = (365 * 400 + 97);
42 const DAYS_PER_100Y: i32 = (365 * 100 + 24);
43 const DAYS_PER_4Y : i32 = (365 * 4 + 1);
45 const DAYS_IN_MONTH : [i32; 12] = [ 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29 ];
48 pub fn from_unix_time(u: u32) -> Option<Time> {
51 let secs = t - LEAPOCH;
52 let mut days = secs / 86400;
53 let mut remsecs = secs % 86400;
60 let mut qc_cycles = days / DAYS_PER_400Y;
61 let mut remdays = days % DAYS_PER_400Y;
64 remdays += DAYS_PER_400Y;
68 let mut c_cycles = remdays / DAYS_PER_100Y;
74 remdays -= c_cycles * DAYS_PER_100Y;
76 let mut q_cycles = remdays / DAYS_PER_4Y;
82 remdays -= q_cycles * DAYS_PER_4Y;
84 let mut remyears = remdays / 365;
90 remdays -= remyears * 365;
93 remyears + 4 * q_cycles + 100 * c_cycles + 400 * qc_cycles;
97 while remdays >= DAYS_IN_MONTH[months as usize] {
98 remdays -= DAYS_IN_MONTH[months as usize];
107 if years + 100 > i32::max_value() || years + 100 < i32::min_value() {
114 hours: remsecs / 3600,
115 minutes: remsecs / 60 % 60,
116 seconds: remsecs % 60,
121 pub fn fmt_time(&self, s: &mut [u8]) {
124 offset += fmt_u32_pad(&mut s[offset..], self.hours as u32, 2, b'0');
128 offset += fmt_u32_pad(&mut s[offset..], self.minutes as u32, 2, b'0');
132 fmt_u32_pad(&mut s[offset..], self.seconds as u32, 2, b'0');