~ruther/simple-clock

ref: 6fbd046c5cdec2a46aa06ef9753192095ad33555 simple-clock/source/src/calendar.rs -rw-r--r-- 2.8 KiB
6fbd046c — Rutherther Merge pull request #1 from Rutherther/add-docs 1 year, 9 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
pub struct Calendar {
    hours: u8,
    minutes: u8,
    seconds: u8,
    day: u8,
    month: u8,
    year: u16,
}

impl Calendar {
    pub fn new(hours: u8, minutes: u8, seconds: u8, day: u8, month: u8, year: u16) -> Self {
        Self {
            hours,
            minutes,
            seconds,
            day,
            month,
            year,
        }
    }

    pub fn from_seconds(base: Calendar, seconds: u32) -> Self {
        let total_seconds = seconds + base.seconds as u32;
        let seconds = total_seconds % 60;

        let total_minutes = total_seconds / 60 + base.minutes as u32;
        let minutes = total_minutes % 60;

        let total_hours = total_minutes / 60 + base.hours as u32;
        let hours = total_hours % 24;

        let total_days = total_hours / 24 + base.day as u32;
        let day = total_days % 30; // TODO...
                                   // the current month and year has to be known prior to the calculation of the day

        Self {
            seconds: seconds as u8,
            minutes: minutes as u8,
            hours: hours as u8,
            day: day as u8,
            month: base.month,
            year: base.year,
        }
    }

    pub fn hours(&self) -> u8 {
        self.hours
    }

    pub fn minutes(&self) -> u8 {
        self.minutes
    }

    pub fn seconds(&self) -> u8 {
        self.seconds
    }

    pub fn day(&self) -> u8 {
        self.day
    }

    pub fn month(&self) -> u8 {
        self.month
    }

    pub fn year(&self) -> u16 {
        self.year
    }

    pub fn second_elapsed(&mut self) {
        self.seconds = (self.seconds + 1) % 60;
        let minute_elapsed = self.seconds == 0;
        self.minutes = (self.minutes + if minute_elapsed { 1 } else { 0 }) % 60;

        let hour_elapsed = minute_elapsed && self.minutes == 0;
        self.hours = (self.hours + if hour_elapsed { 1 } else { 0 }) % 24;

        let day_elapsed = hour_elapsed && self.hours == 0;
        let day = self.day - 1 + if day_elapsed { 1 } else { 0 };
        let days_in_month = Self::days_in_month(self.month, Self::is_leap_year(self.year));
        self.day = day % days_in_month + 1;

        let month_elapsed = day_elapsed && self.day == 1;
        self.month = (self.month - 1 + if month_elapsed { 1 } else { 0 }) % 12 + 1;
        let year_elapsed = month_elapsed && self.month == 1;
        self.year += if year_elapsed { 1 } else { 0 };
    }

    fn is_leap_year(year: u16) -> bool {
        matches!(year % 4, 0 if year % 100 != 0 || year % 400 == 0)
    }

    fn days_in_month(month: u8, leap_year: bool) -> u8 {
        match month {
            2 if leap_year => 29,
            2 => 28,
            1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
            4 | 6 | 9 | 11 => 31,
            _ => panic!(),
        }
    }
}
Do not follow this link