use std::time::{SystemTime, UNIX_EPOCH};
use std::collections::BTreeMap;
pub fn timestamp() -> String {
let now: u128 = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
millis_to_iso_8601(&now)
}
fn count_years_from_days(days: &u128) -> (u128, u128, bool){
let mut days: u128 = *days;
let mut year: u128 = 1970;
let mut leap_year: bool = false;
if days > (2*365){
days = days - (2*365);
year = year + 2;
};
let leap_cycles = days / (365 * 4 + 1);
days = days - (leap_cycles * (365 * 4 + 1));
let years = days / 365;
days = days - (years * 365);
year = year + (leap_cycles * 4) + years;
if ((year/4)*4) == year{
leap_year = true;
};
(year, days, leap_year)
}
fn get_month_from_day(days: &u128, leap: &bool) -> u8{
let mut months = BTreeMap::new();
months.insert(1_u8, 31_i16);
if *leap{
months.insert(2_u8, 29_i16);
} else {
months.insert(2_u8, 28_i16);
};
months.insert(3_u8, 31_i16);
months.insert(4_u8, 30_i16);
months.insert(5_u8, 31_i16);
months.insert(6_u8, 30_i16);
months.insert(7_u8, 31_i16);
months.insert(8_u8, 31_i16);
months.insert(9_u8, 30_i16);
months.insert(10_u8, 31_i16);
months.insert(11_u8, 30_i16);
months.insert(12_u8, 31_i16);
let mut month:u8 = 0;
let mut days = i16::try_from(*days).ok().unwrap();
for (k,v) in months{
days = days - v;
if days < 1{
month = k;
break;
}
}
month
}
fn millis_to_iso_8601(time: &u128) -> String {
let mut milliseconds = *time;
let day: u128 = 86_400_000;
let hour: u128 = 3_600_000;
let minute: u128 = 60_000;
let second: u128 = 1_000;
let days = milliseconds/day;
milliseconds = milliseconds - (days * day);
let hours = milliseconds/hour;
milliseconds = milliseconds - (hours * hour);
let minutes = milliseconds/minute;
milliseconds = milliseconds - (minutes * minute);
let seconds = milliseconds/second;
milliseconds = milliseconds - (seconds * second);
let (years, days, leap_year) = count_years_from_days(&days);
let month = get_month_from_day(&days, &leap_year);
format!("{:0>4}-{:0>2}-{:0>2}T{:0>2}:{:0>2}:{:0>2}.{:0>3}Z", years, month, days, hours, minutes, seconds, milliseconds)
}