doom_2038/
lib.rs

1use std::thread;
2use std::time::{Duration, SystemTime, UNIX_EPOCH};
3
4/// The Unix timestamp for the Year 2038 problem:
5/// 2038-01-19 03:14:07 UTC. This timestamp represents
6/// the maximum value for a 32-bit signed integer.
7///
8/// # Examples
9///
10/// ```
11/// let u32_limit = DOOM_TS;  
12/// assert_eq!(u32_limit, 2_147_483_647);
13/// ```
14pub const DOOM_TS: u64 = 2_147_483_647;
15
16/// ammount of seconds in a minute
17pub const SECONDS_IN_MINUTE: u64 = 60;
18/// ammount of seconds in a hour
19pub const SECONDS_IN_HOUR: u64 = 3600;
20/// ammount of seconds in a day
21pub const SECONDS_IN_DAY: u64 = 86_400; // 24 * 60 * 60
22/// ammount of seconds in a year (why ts scarily small)
23pub const SECONDS_IN_YEAR: u64 = 31_536_000; // 365 * 24 * 60 * 60
24
25/// Calculates the time left until the Year 2038 problem occurs,
26/// returning it as a `Duration`.
27///
28/// This function computes the difference between the current time
29/// and the DOOM_TS constant, which marks the limit of a 32-bit
30/// unsigned integer. If the current time is past the doom timestamp,
31/// this will return a `Duration` of zero.
32///
33/// # Returns
34///
35/// A `Duration` representing the time remaining until the Year 2038 problem.
36///
37/// # Examples
38///
39/// ```
40/// let duration_left = time_left();
41/// println!("Time left until 2038 problem: {:?}", duration_left);
42/// ```
43pub fn time_left() -> Duration {
44    let now = SystemTime::now()
45        .duration_since(UNIX_EPOCH)
46        .expect("Time went backwards");
47    Duration::from_secs(DOOM_TS.saturating_sub(now.as_secs()))
48}
49
50/// Displays the time left until whatever in a
51/// human-readable format.
52///
53/// # Parameters
54///
55/// - `duration`: A `Duration` indicating the time left.
56///
57/// # Examples
58///
59/// ```
60/// let remaining_time = Duration::new(5000, 0); // Example duration
61/// print_time_left(remaining_time);
62/// ```
63pub fn print_time_left(duration: Duration) {
64    let total_seconds = duration.as_secs();
65
66    if total_seconds >= SECONDS_IN_YEAR {
67        let years = total_seconds / SECONDS_IN_YEAR;
68        let remaining_seconds = total_seconds % SECONDS_IN_YEAR;
69
70        let days = remaining_seconds / SECONDS_IN_DAY;
71        let remaining_seconds = remaining_seconds % SECONDS_IN_DAY;
72
73        let hours = remaining_seconds / SECONDS_IN_HOUR;
74        let remaining_seconds = remaining_seconds % SECONDS_IN_HOUR;
75
76        let minutes = remaining_seconds / SECONDS_IN_MINUTE;
77        let seconds = remaining_seconds % SECONDS_IN_MINUTE;
78
79        println!(
80            "{} years, {} days, {} hours, {} minutes, {} seconds",
81            years, days, hours, minutes, seconds
82        );
83    } else if total_seconds >= SECONDS_IN_DAY {
84        let days = total_seconds / SECONDS_IN_DAY;
85        let remaining_seconds = total_seconds % SECONDS_IN_DAY;
86
87        let hours = remaining_seconds / SECONDS_IN_HOUR;
88        let remaining_seconds = remaining_seconds % SECONDS_IN_HOUR;
89
90        let minutes = remaining_seconds / SECONDS_IN_MINUTE;
91        let seconds = remaining_seconds % SECONDS_IN_MINUTE;
92
93        println!(
94            "{} days, {} hours, {} minutes, {} seconds",
95            days, hours, minutes, seconds
96        );
97    } else if total_seconds >= SECONDS_IN_HOUR {
98        let hours = total_seconds / SECONDS_IN_HOUR;
99        let remaining_seconds = total_seconds % SECONDS_IN_HOUR;
100
101        let minutes = remaining_seconds / SECONDS_IN_MINUTE;
102        let seconds = remaining_seconds % SECONDS_IN_MINUTE;
103
104        println!("{} hours, {} minutes, {} seconds", hours, minutes, seconds);
105    } else if total_seconds >= SECONDS_IN_MINUTE {
106        let minutes = total_seconds / SECONDS_IN_MINUTE;
107        let seconds = total_seconds % SECONDS_IN_MINUTE;
108
109        println!("{} minutes, {} seconds", minutes, seconds);
110    } else {
111        println!("{} seconds", total_seconds);
112    }
113}
114
115/// Runs the doom countdown either continuously or just once,
116/// based on the `countdown` flag.
117///
118/// If `countdown` is set to true, the function enters a loop
119/// that refreshes and prints the time left every second.
120/// If false, it simply prints the time left once.
121///
122/// # Parameters
123///
124/// - `countdown`: A boolean that determines whether to run the countdown continuously or just once. (true = continously)
125///
126/// # Examples
127///
128/// ```
129/// // To run the countdown continuously:
130/// doom(true);
131///
132/// // To print the time left once:
133/// doom(false);
134/// ```
135pub fn doom(countdown: bool) {
136    if countdown {
137        loop {
138            print_time_left(time_left());
139            thread::sleep(Duration::from_secs(1));
140        }
141    } else {
142        print_time_left(time_left());
143    }
144}