use time::Tm;
pub (crate) fn adv_year(time: &mut Tm) {
time.tm_year += 1;
}
pub (crate) fn adv_month(time: &mut Tm) {
time.tm_mon += 1;
if time.tm_mon > 11 {
time.tm_mon = 0;
adv_year(time);
}
}
pub (crate) fn adv_day(time: &mut Tm) {
time.tm_wday = (time.tm_wday + 1) % 7; time.tm_mday += 1;
let is_leap_year = {
let year = time.tm_year + 1900;
if year % 400 == 0
|| (year % 4 == 0 && year % 100 != 0) {
true
} else {
false
}
};
let days_in_year = if is_leap_year { 366 } else { 365 };
time.tm_yday = (time.tm_yday + 1) % days_in_year;
match time.tm_mon {
0 | 2 | 4 | 6 | 7 | 9 | 11 => {
if time.tm_mday > 31 {
time.tm_mday = 1;
adv_month(time);
}
},
3 | 5 | 8 | 10 => {
if time.tm_mday > 30 {
time.tm_mday = 1;
adv_month(time);
}
},
1 => {
let mdays = if is_leap_year { 29 } else { 28 };
if time.tm_mday > mdays {
time.tm_mday = 1;
adv_month(time);
}
},
_ => {}, }
}
pub (crate) fn adv_hour(time: &mut Tm) {
time.tm_hour += 1;
if time.tm_hour > 23 {
time.tm_hour = 0;
adv_day(time);
}
}
pub (crate) fn adv_minute(time: &mut Tm) {
time.tm_min += 1;
if time.tm_min > 59 {
time.tm_min = 0;
adv_hour(time);
}
}
#[cfg(test)]
mod tests {
use super::*;
use expectest::prelude::*;
use test_helpers::get_tm;
use test_helpers::normal;
use time::{Timespec, at_utc};
#[test]
pub fn test_adv_year() {
let mut tm = get_tm(2017, 10, 6, 12, 24, 0);
adv_year(&mut tm);
expect!(normal(&tm)).to(be_equal_to(get_tm(2018, 10, 6, 12, 24, 0)));
}
#[test]
pub fn test_adv_month() {
let mut tm = get_tm(2017, 1, 1, 12, 0, 0);
adv_month(&mut tm);
expect!(normal(&tm)).to(be_equal_to(get_tm(2017, 2, 1, 12, 0, 0)));
let mut tm = get_tm(2017, 12, 1, 0, 0, 0);
adv_month(&mut tm);
expect!(normal(&tm)).to(be_equal_to(get_tm(2018, 1, 1, 0, 0, 0)));
}
#[test]
pub fn test_adv_day_on_mday() {
let timespec = Timespec::new(1483228800, 0);
let mut tm = at_utc(timespec);
let days_in_months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
for tm_year in 117 .. 120 {
expect!(tm.tm_year).to(be_equal_to(tm_year));
for days_in_month in days_in_months.iter() {
let bound = days_in_month + 1; for expected_day in 1..bound {
expect!(tm.tm_mday).to(be_equal_to(expected_day));
adv_day(&mut tm);
}
}
}
expect!(tm.tm_year).to(be_equal_to(120));
let days_in_months = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
for days_in_month in days_in_months.iter() {
let bound = days_in_month + 1; for expected_day in 1..bound {
expect!(tm.tm_mday).to(be_equal_to(expected_day));
adv_day(&mut tm);
}
}
expect!(tm.tm_year).to(be_equal_to(121));
}
#[test]
pub fn test_adv_day_on_wday() {
let timespec = Timespec::new(1483228800, 0);
let mut tm = at_utc(timespec);
expect!(tm.tm_wday).to(be_equal_to(0));
adv_day(&mut tm);
expect!(tm.tm_wday).to(be_equal_to(1));
adv_day(&mut tm);
expect!(tm.tm_wday).to(be_equal_to(2));
adv_day(&mut tm);
expect!(tm.tm_wday).to(be_equal_to(3));
adv_day(&mut tm);
expect!(tm.tm_wday).to(be_equal_to(4));
adv_day(&mut tm);
expect!(tm.tm_wday).to(be_equal_to(5));
adv_day(&mut tm);
expect!(tm.tm_wday).to(be_equal_to(6));
adv_day(&mut tm);
expect!(tm.tm_wday).to(be_equal_to(0));
let mut expected = 0;
for _ in 0 .. 1460 {
expected = (expected + 1) % 7;
adv_day(&mut tm);
expect!(tm.tm_wday).to(be_equal_to(expected));
}
let mut tm = at_utc(timespec);
expect!(tm.tm_year).to(be_equal_to(117)); expect!(tm.tm_wday).to(be_equal_to(0));
for _ in 0 .. 365 {
adv_day(&mut tm);
}
expect!(tm.tm_year).to(be_equal_to(118)); expect!(tm.tm_wday).to(be_equal_to(1)); }
#[test]
pub fn test_adv_day_on_yday() {
let timespec = Timespec::new(1483228800, 0);
let mut tm = at_utc(timespec);
expect!(tm.tm_year).to(be_equal_to(117));
expect!(tm.tm_yday).to(be_equal_to(0));
for expected_day in 0 .. 365 {
expect!(tm.tm_year).to(be_equal_to(117)); expect!(tm.tm_yday).to(be_equal_to(expected_day));
adv_day(&mut tm);
}
expect!(tm.tm_year).to(be_equal_to(118));
expect!(tm.tm_yday).to(be_equal_to(0));
for year in 118 .. 120 {
for expected_day in 0 .. 365 {
expect!(tm.tm_year).to(be_equal_to(year));
expect!(tm.tm_yday).to(be_equal_to(expected_day));
adv_day(&mut tm);
}
}
expect!(tm.tm_year).to(be_equal_to(120));
expect!(tm.tm_yday).to(be_equal_to(0));
for expected_day in 0 .. 366 {
expect!(tm.tm_year).to(be_equal_to(120));
expect!(tm.tm_yday).to(be_equal_to(expected_day));
adv_day(&mut tm);
}
expect!(tm.tm_year).to(be_equal_to(121));
expect!(tm.tm_yday).to(be_equal_to(0));
}
}