tools/systemd/time: let libc normalize time for us
mktime/gmtime can normalize time and even can handle special timezone cases like the fact that the time 2:30 on specific day/timezone combos do not exists we have to convert the signature of all functions that use normalize_time since mktime/gmtime can return an EOVERFLOW but if this happens there is no way we can find a good time anyway since normalize_time will always set wday according to the rest of the time, remove set_wday Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
28a0a9343c
commit
c931c87173
|
@ -180,11 +180,11 @@ pub fn compute_next_event(
|
||||||
.find(|d| event.days.contains(WeekDays::from_bits(1<<d).unwrap()))
|
.find(|d| event.days.contains(WeekDays::from_bits(1<<d).unwrap()))
|
||||||
{
|
{
|
||||||
// try next day
|
// try next day
|
||||||
t.add_days(n - day_num, true);
|
t.add_days(n - day_num, true)?;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// try next week
|
// try next week
|
||||||
t.add_days(7 - day_num, true);
|
t.add_days(7 - day_num, true)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,11 +196,11 @@ pub fn compute_next_event(
|
||||||
if !DateTimeValue::list_contains(&event.hour, hour) {
|
if !DateTimeValue::list_contains(&event.hour, hour) {
|
||||||
if let Some(n) = DateTimeValue::find_next(&event.hour, hour) {
|
if let Some(n) = DateTimeValue::find_next(&event.hour, hour) {
|
||||||
// test next hour
|
// test next hour
|
||||||
t.set_time(n as libc::c_int, 0, 0);
|
t.set_time(n as libc::c_int, 0, 0)?;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// test next day
|
// test next day
|
||||||
t.add_days(1, true);
|
t.add_days(1, true)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,11 +212,11 @@ pub fn compute_next_event(
|
||||||
if !DateTimeValue::list_contains(&event.minute, minute) {
|
if !DateTimeValue::list_contains(&event.minute, minute) {
|
||||||
if let Some(n) = DateTimeValue::find_next(&event.minute, minute) {
|
if let Some(n) = DateTimeValue::find_next(&event.minute, minute) {
|
||||||
// test next minute
|
// test next minute
|
||||||
t.set_min_sec(n as libc::c_int, 0);
|
t.set_min_sec(n as libc::c_int, 0)?;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// test next hour
|
// test next hour
|
||||||
t.set_time(t.hour() + 1, 0, 0);
|
t.set_time(t.hour() + 1, 0, 0)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,11 +228,11 @@ pub fn compute_next_event(
|
||||||
if !DateTimeValue::list_contains(&event.second, second) {
|
if !DateTimeValue::list_contains(&event.second, second) {
|
||||||
if let Some(n) = DateTimeValue::find_next(&event.second, second) {
|
if let Some(n) = DateTimeValue::find_next(&event.second, second) {
|
||||||
// test next second
|
// test next second
|
||||||
t.set_sec(n as libc::c_int);
|
t.set_sec(n as libc::c_int)?;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// test next min
|
// test next min
|
||||||
t.set_min_sec(t.min() + 1, 0);
|
t.set_min_sec(t.min() + 1, 0)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,6 @@ pub struct TmEditor {
|
||||||
t: libc::tm,
|
t: libc::tm,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_leap_year(year: libc::c_int) -> bool {
|
|
||||||
if year % 4 != 0 { return false; }
|
|
||||||
if year % 100 != 0 { return true; }
|
|
||||||
if year % 400 != 0 { return false; }
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn days_in_month(mon: libc::c_int, year: libc::c_int) -> libc::c_int {
|
|
||||||
|
|
||||||
let mon = mon % 12;
|
|
||||||
|
|
||||||
static MAP: &[libc::c_int] = &[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
||||||
|
|
||||||
if mon == 1 && is_leap_year(year) { return 29; }
|
|
||||||
|
|
||||||
MAP[mon as usize]
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TmEditor {
|
impl TmEditor {
|
||||||
|
|
||||||
pub fn new(epoch: i64, utc: bool) -> Result<Self, Error> {
|
pub fn new(epoch: i64, utc: bool) -> Result<Self, Error> {
|
||||||
|
@ -39,8 +21,8 @@ impl TmEditor {
|
||||||
Ok(epoch)
|
Ok(epoch)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_days(&mut self, days: libc::c_int, reset_time: bool) {
|
pub fn add_days(&mut self, days: libc::c_int, reset_time: bool) -> Result<(), Error> {
|
||||||
if days == 0 { return; }
|
if days == 0 { return Ok(()); }
|
||||||
if reset_time {
|
if reset_time {
|
||||||
self.t.tm_hour = 0;
|
self.t.tm_hour = 0;
|
||||||
self.t.tm_min = 0;
|
self.t.tm_min = 0;
|
||||||
|
@ -48,7 +30,7 @@ impl TmEditor {
|
||||||
}
|
}
|
||||||
self.t.tm_mday += days;
|
self.t.tm_mday += days;
|
||||||
self.t.tm_wday += days;
|
self.t.tm_wday += days;
|
||||||
self.wrap_time();
|
self.normalize_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hour(&self) -> libc::c_int { self.t.tm_hour }
|
pub fn hour(&self) -> libc::c_int { self.t.tm_hour }
|
||||||
|
@ -60,95 +42,56 @@ impl TmEditor {
|
||||||
(self.t.tm_wday + 6) % 7
|
(self.t.tm_wday + 6) % 7
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_time(&mut self, hour: libc::c_int, min: libc::c_int, sec: libc::c_int) {
|
pub fn set_time(&mut self, hour: libc::c_int, min: libc::c_int, sec: libc::c_int) -> Result<(), Error> {
|
||||||
self.t.tm_hour = hour;
|
self.t.tm_hour = hour;
|
||||||
self.t.tm_min = min;
|
self.t.tm_min = min;
|
||||||
self.t.tm_sec = sec;
|
self.t.tm_sec = sec;
|
||||||
self.wrap_time();
|
self.normalize_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_min_sec(&mut self, min: libc::c_int, sec: libc::c_int) {
|
pub fn set_min_sec(&mut self, min: libc::c_int, sec: libc::c_int) -> Result<(), Error> {
|
||||||
self.t.tm_min = min;
|
self.t.tm_min = min;
|
||||||
self.t.tm_sec = sec;
|
self.t.tm_sec = sec;
|
||||||
self.wrap_time();
|
self.normalize_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_time(&mut self) {
|
fn normalize_time(&mut self) -> Result<(), Error> {
|
||||||
|
// libc normalizes it for us
|
||||||
// sec: 0..59
|
if self.utc {
|
||||||
if self.t.tm_sec >= 60 {
|
timegm(&mut self.t)?;
|
||||||
self.t.tm_min += self.t.tm_sec / 60;
|
} else {
|
||||||
self.t.tm_sec %= 60;
|
timelocal(&mut self.t)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
// min: 0..59
|
|
||||||
if self.t.tm_min >= 60 {
|
|
||||||
self.t.tm_hour += self.t.tm_min / 60;
|
|
||||||
self.t.tm_min %= 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
// hour: 0..23
|
|
||||||
if self.t.tm_hour >= 24 {
|
|
||||||
self.t.tm_mday += self.t.tm_hour / 24;
|
|
||||||
self.t.tm_wday += self.t.tm_hour / 24;
|
|
||||||
self.t.tm_hour %= 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate to 0..($days_in_mon-1)
|
|
||||||
self.t.tm_mday -= 1;
|
|
||||||
loop {
|
|
||||||
let days_in_mon = days_in_month(self.t.tm_mon, self.t.tm_year);
|
|
||||||
if self.t.tm_mday < days_in_mon { break; }
|
|
||||||
// Wrap one month
|
|
||||||
self.t.tm_mday -= days_in_mon;
|
|
||||||
self.t.tm_mon += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate back to 1..$days_in_mon
|
|
||||||
self.t.tm_mday += 1;
|
|
||||||
|
|
||||||
// mon: 0..11
|
|
||||||
if self.t.tm_mon >= 12 {
|
|
||||||
self.t.tm_year += self.t.tm_mon / 12;
|
|
||||||
self.t.tm_mon %= 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.t.tm_wday %= 7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_sec(&mut self, v: libc::c_int) {
|
pub fn set_sec(&mut self, v: libc::c_int) -> Result<(), Error> {
|
||||||
self.t.tm_sec = v;
|
self.t.tm_sec = v;
|
||||||
self.wrap_time();
|
self.normalize_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_min(&mut self, v: libc::c_int) {
|
pub fn set_min(&mut self, v: libc::c_int) -> Result<(), Error> {
|
||||||
self.t.tm_min = v;
|
self.t.tm_min = v;
|
||||||
self.wrap_time();
|
self.normalize_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_hour(&mut self, v: libc::c_int) {
|
pub fn set_hour(&mut self, v: libc::c_int) -> Result<(), Error> {
|
||||||
self.t.tm_hour = v;
|
self.t.tm_hour = v;
|
||||||
self.wrap_time();
|
self.normalize_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mday(&mut self, v: libc::c_int) {
|
pub fn set_mday(&mut self, v: libc::c_int) -> Result<(), Error> {
|
||||||
self.t.tm_mday = v;
|
self.t.tm_mday = v;
|
||||||
self.wrap_time();
|
self.normalize_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mon(&mut self, v: libc::c_int) {
|
pub fn set_mon(&mut self, v: libc::c_int) -> Result<(), Error> {
|
||||||
self.t.tm_mon = v;
|
self.t.tm_mon = v;
|
||||||
self.wrap_time();
|
self.normalize_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_year(&mut self, v: libc::c_int) {
|
pub fn set_year(&mut self, v: libc::c_int) -> Result<(), Error> {
|
||||||
self.t.tm_year = v;
|
self.t.tm_year = v;
|
||||||
self.wrap_time();
|
self.normalize_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_wday(&mut self, v: libc::c_int) {
|
|
||||||
self.t.tm_wday = v;
|
|
||||||
self.wrap_time();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue