public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Dominik Csapak <d.csapak@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup v2 02/11] tools/systemd/time: let libc normalize time for us
Date: Fri,  4 Sep 2020 14:33:25 +0200	[thread overview]
Message-ID: <20200904123334.3731-3-d.csapak@proxmox.com> (raw)
In-Reply-To: <20200904123334.3731-1-d.csapak@proxmox.com>

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>
---
 src/tools/systemd/time.rs      |  16 ++---
 src/tools/systemd/tm_editor.rs | 109 ++++++++-------------------------
 2 files changed, 34 insertions(+), 91 deletions(-)

diff --git a/src/tools/systemd/time.rs b/src/tools/systemd/time.rs
index 2a1bf8a3..0d114eb8 100644
--- a/src/tools/systemd/time.rs
+++ b/src/tools/systemd/time.rs
@@ -180,11 +180,11 @@ pub fn compute_next_event(
                     .find(|d| event.days.contains(WeekDays::from_bits(1<<d).unwrap()))
                 {
                     // try next day
-                    t.add_days(n - day_num, true);
+                    t.add_days(n - day_num, true)?;
                     continue;
                 } else {
                     // try next week
-                    t.add_days(7 - day_num, true);
+                    t.add_days(7 - day_num, true)?;
                     continue;
                 }
             }
@@ -196,11 +196,11 @@ pub fn compute_next_event(
             if !DateTimeValue::list_contains(&event.hour, hour) {
                 if let Some(n) = DateTimeValue::find_next(&event.hour, 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;
                 } else {
                     // test next day
-                    t.add_days(1, true);
+                    t.add_days(1, true)?;
                     continue;
                 }
             }
@@ -212,11 +212,11 @@ pub fn compute_next_event(
             if !DateTimeValue::list_contains(&event.minute, minute) {
                 if let Some(n) = DateTimeValue::find_next(&event.minute, 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;
                 } else {
                     // test next hour
-                    t.set_time(t.hour() + 1, 0, 0);
+                    t.set_time(t.hour() + 1, 0, 0)?;
                     continue;
                 }
             }
@@ -228,11 +228,11 @@ pub fn compute_next_event(
             if !DateTimeValue::list_contains(&event.second, second) {
                 if let Some(n) = DateTimeValue::find_next(&event.second, second) {
                     // test next second
-                    t.set_sec(n as libc::c_int);
+                    t.set_sec(n as libc::c_int)?;
                     continue;
                 } else {
                     // test next min
-                    t.set_min_sec(t.min() + 1, 0);
+                    t.set_min_sec(t.min() + 1, 0)?;
                     continue;
                 }
             }
diff --git a/src/tools/systemd/tm_editor.rs b/src/tools/systemd/tm_editor.rs
index 1e8e4d07..4a14a975 100644
--- a/src/tools/systemd/tm_editor.rs
+++ b/src/tools/systemd/tm_editor.rs
@@ -7,24 +7,6 @@ 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> {
@@ -39,8 +21,8 @@ impl TmEditor {
         Ok(epoch)
     }
 
-    pub fn add_days(&mut self, days: libc::c_int, reset_time: bool) {
-        if days == 0 { return; }
+    pub fn add_days(&mut self, days: libc::c_int, reset_time: bool) -> Result<(), Error> {
+        if days == 0 { return Ok(()); }
         if reset_time {
             self.t.tm_hour = 0;
             self.t.tm_min = 0;
@@ -48,7 +30,7 @@ impl TmEditor {
         }
         self.t.tm_mday += days;
         self.t.tm_wday += days;
-        self.wrap_time();
+        self.normalize_time()
     }
 
     pub fn hour(&self) -> libc::c_int { self.t.tm_hour }
@@ -60,95 +42,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) {
+    pub fn set_mon(&mut self, v: libc::c_int) -> Result<(), Error> {
         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.wrap_time();
+        self.normalize_time()
     }
-
-    pub fn set_wday(&mut self, v: libc::c_int) {
-        self.t.tm_wday = v;
-        self.wrap_time();
-    }
-
 }
-- 
2.20.1





  parent reply	other threads:[~2020-09-04 12:34 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-04 12:33 [pbs-devel] [PATCH proxmox-backup v2 00/11] implement dates for calendarevents Dominik Csapak
2020-09-04 12:33 ` [pbs-devel] [PATCH proxmox-backup v2 01/11] tools/systemd/tm_editor: remove TMChanges optimization Dominik Csapak
2020-09-04 12:33 ` Dominik Csapak [this message]
2020-09-04 12:33 ` [pbs-devel] [PATCH proxmox-backup v2 03/11] tools/systemd/time: move continue out of the if/else Dominik Csapak
2020-09-04 12:33 ` [pbs-devel] [PATCH proxmox-backup v2 04/11] tools/systemd/time: convert the resulting timestamp into an option Dominik Csapak
2020-09-04 12:33 ` [pbs-devel] [PATCH proxmox-backup v2 05/11] tools/systemd/tm_editor: remove reset_time from add_days and document it Dominik Csapak
2020-09-04 12:33 ` [pbs-devel] [PATCH proxmox-backup v2 06/11] tools/systemd/parse_time: error out on invalid ranges Dominik Csapak
2020-09-04 12:33 ` [pbs-devel] [PATCH proxmox-backup v2 07/11] tools/systemd/time: fix selection for multiple options Dominik Csapak
2020-09-04 13:38   ` Dietmar Maurer
2020-09-07  6:27     ` Dominik Csapak
2020-09-04 12:33 ` [pbs-devel] [PATCH proxmox-backup v2 08/11] tools/systemd/tm_editor: move conversion of the year into getter and setter Dominik Csapak
2020-09-04 12:33 ` [pbs-devel] [PATCH proxmox-backup v2 09/11] tools/systemd/tm_editor: add setter/getter for months/years/days Dominik Csapak
2020-09-04 12:33 ` [pbs-devel] [PATCH proxmox-backup v2 10/11] tools/systemd/time: fix signed conversion Dominik Csapak
2020-09-04 12:33 ` [pbs-devel] [PATCH proxmox-backup v2 11/11] tools/systemd/time: enable dates for calendarevents Dominik Csapak
2020-09-04 13:36 ` [pbs-devel] applied: [PATCH proxmox-backup v2 00/11] implement " Dietmar Maurer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200904123334.3731-3-d.csapak@proxmox.com \
    --to=d.csapak@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal