]> git.proxmox.com Git - proxmox-backup.git/blobdiff - src/tools/systemd/tm_editor.rs
www/OnlineHelpInfo.js: update for syncjobs
[proxmox-backup.git] / src / tools / systemd / tm_editor.rs
index 1e8e4d079aeb96c46cd206eb296131995bc047ac..770bb280803e42d2687e5534ee95a5048559349e 100644 (file)
@@ -7,50 +7,54 @@ pub struct TmEditor {
     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 {
 
     pub fn new(epoch: i64, utc: bool) -> Result<Self, Error> {
-        let mut t = if utc { gmtime(epoch)? } else { localtime(epoch)? };
-        t.tm_year += 1900; // real years for clarity
+        let t = if utc { gmtime(epoch)? } else { localtime(epoch)? };
         Ok(Self { utc, t })
     }
 
     pub fn into_epoch(mut self) -> Result<i64, Error> {
-        self.t.tm_year -= 1900;
         let epoch = if self.utc { timegm(&mut self.t)? } else { timelocal(&mut self.t)? };
         Ok(epoch)
     }
 
-    pub fn add_days(&mut self, days: libc::c_int, reset_time: bool) {
-        if days == 0 { return; }
-        if reset_time {
-            self.t.tm_hour = 0;
-            self.t.tm_min = 0;
-            self.t.tm_sec = 0;
-        }
+    /// increases the year by 'years' and resets all smaller fields to their minimum
+    pub fn add_years(&mut self, years: libc::c_int) -> Result<(), Error> {
+        if years == 0 { return Ok(()); }
+        self.t.tm_mon = 0;
+        self.t.tm_mday = 1;
+        self.t.tm_hour = 0;
+        self.t.tm_min = 0;
+        self.t.tm_sec = 0;
+        self.t.tm_year += years;
+        self.normalize_time()
+    }
+
+    /// increases the month by 'months' and resets all smaller fields to their minimum
+    pub fn add_months(&mut self, months: libc::c_int) -> Result<(), Error> {
+        if months == 0 { return Ok(()); }
+        self.t.tm_mday = 1;
+        self.t.tm_hour = 0;
+        self.t.tm_min = 0;
+        self.t.tm_sec = 0;
+        self.t.tm_mon += months;
+        self.normalize_time()
+    }
+
+    /// increases the day by 'days' and resets all smaller fields to their minimum
+    pub fn add_days(&mut self, days: libc::c_int) -> Result<(), Error> {
+        if days == 0 { return Ok(()); }
+        self.t.tm_hour = 0;
+        self.t.tm_min = 0;
+        self.t.tm_sec = 0;
         self.t.tm_mday += days;
-        self.t.tm_wday += days;
-        self.wrap_time();
+        self.normalize_time()
     }
 
+    pub fn year(&self) -> libc::c_int { self.t.tm_year + 1900 } // see man mktime
+    pub fn month(&self) -> libc::c_int { self.t.tm_mon + 1 }
+    pub fn day(&self) -> libc::c_int { self.t.tm_mday }
     pub fn hour(&self) -> libc::c_int { self.t.tm_hour }
     pub fn min(&self) -> libc::c_int { self.t.tm_min }
     pub fn sec(&self) -> libc::c_int { self.t.tm_sec }
@@ -60,95 +64,56 @@ impl TmEditor {
         (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_min = min;
         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_sec = sec;
-        self.wrap_time();
+        self.normalize_time()
     }
 
-    fn wrap_time(&mut self) {
-
-        // sec: 0..59
-        if self.t.tm_sec >= 60 {
-            self.t.tm_min += self.t.tm_sec / 60;
-            self.t.tm_sec %= 60;
-        }
-
-        // 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;
+    fn normalize_time(&mut self) -> Result<(), Error> {
+        // libc normalizes it for us
+        if self.utc {
+            timegm(&mut self.t)?;
+        } else {
+            timelocal(&mut self.t)?;
         }
-
-        self.t.tm_wday %= 7;
+        Ok(())
     }
 
-    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.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.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.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.wrap_time();
+        self.normalize_time()
     }
 
-    pub fn set_mon(&mut self, v: libc::c_int) {
-        self.t.tm_mon = v;
-        self.wrap_time();
+    pub fn set_mon(&mut self, v: libc::c_int) -> Result<(), Error> {
+        self.t.tm_mon = v - 1;
+        self.normalize_time()
     }
 
-    pub fn set_year(&mut self, v: libc::c_int) {
-        self.t.tm_year = v;
-        self.wrap_time();
+    pub fn set_year(&mut self, v: libc::c_int) -> Result<(), Error> {
+        self.t.tm_year = v - 1900;
+        self.normalize_time()
     }
-
-    pub fn set_wday(&mut self, v: libc::c_int) {
-        self.t.tm_wday = v;
-        self.wrap_time();
-    }
-
 }