|
1 |
| -##Clock in pt2thon## |
2 |
| - |
3 |
| -t1 = input("Init schedule : ") # first schedule |
4 |
| -HH1 = int(t1[0] + t1[1]) |
5 |
| -MM1 = int(t1[3] + t1[4]) |
6 |
| -SS1 = int(t1[6] + t1[7]) |
7 |
| - |
8 |
| -t2 = input("Final schedule : ") # second schedule |
9 |
| -HH2 = int(t2[0] + t2[1]) |
10 |
| -MM2 = int(t2[3] + t2[4]) |
11 |
| -SS2 = int(t2[6] + t2[7]) |
12 |
| - |
13 |
| -tt1 = (HH1 * 3600) + (MM1 * 60) + SS1 # total schedule 1 |
14 |
| -tt2 = (HH2 * 3600) + (MM2 * 60) + SS2 # total schedule 2 |
15 |
| -tt3 = tt2 - tt1 # difference between tt2 e tt1 |
16 |
| - |
17 |
| -# Part Math |
18 |
| -if tt3 < 0: |
19 |
| - # If the difference between tt2 e tt1 for negative : |
20 |
| - |
21 |
| - a = 86400 - tt1 # 86400 is seconds in 1 day; |
22 |
| - a2 = a + tt2 # a2 is the difference between 1 day e the <hours var>; |
23 |
| - Ht = a2 // 3600 # Ht is hours calculated; |
24 |
| - |
25 |
| - a = a2 % 3600 # Convert 'a' in seconds; |
26 |
| - Mt = a // 60 # Mt is minutes calculated; |
27 |
| - St = a % 60 # St is seconds calculated; |
28 |
| - |
29 |
| -else: |
30 |
| - # If the difference between tt2 e tt1 for positive : |
31 |
| - |
32 |
| - Ht = tt3 // 3600 # Ht is hours calculated; |
33 |
| - z = tt3 % 3600 # 'z' is tt3 converting in hours by seconds |
34 |
| - |
35 |
| - Mt = z // 60 # Mt is minutes calculated; |
36 |
| - St = tt3 % 60 # St is seconds calculated; |
37 |
| - |
38 |
| -# special condition below : |
39 |
| -if Ht < 10: |
40 |
| - h = "0" + str(Ht) |
41 |
| - Ht = h |
42 |
| -if Mt < 10: |
43 |
| - m = "0" + str(Mt) |
44 |
| - Mt = m |
45 |
| -if St < 10: |
46 |
| - s = "0" + str(St) |
47 |
| - St = s |
48 |
| -# add '0' to the empty spaces (caused by previous operations) in the final result! |
49 |
| - |
50 |
| -print( |
51 |
| - "final result is :", str(Ht) + ":" + str(Mt) + ":" + str(St) |
52 |
| -) # final result (formatted in clock) |
| 1 | +"""Clock Time Difference Calculator |
| 2 | +
|
| 3 | +Calculates the time difference between two 24-hour formatted times (HH:MM:SS) |
| 4 | +and returns the result in the same HH:MM:SS format. Handles cases where the |
| 5 | +second time is earlier than the first (crosses midnight). |
| 6 | +""" |
| 7 | + |
| 8 | +import sys |
| 9 | + |
| 10 | + |
| 11 | +def parse_time(time_str: str) -> tuple[int, int, int]: |
| 12 | + """Parse a time string in HH:MM:SS format into hours, minutes, seconds. |
| 13 | +
|
| 14 | + Args: |
| 15 | + time_str: Time string in "HH:MM:SS" format. |
| 16 | +
|
| 17 | + Returns: |
| 18 | + Tuple containing (hours, minutes, seconds). |
| 19 | +
|
| 20 | + Raises: |
| 21 | + ValueError: If input format is invalid or values are out of range. |
| 22 | + """ |
| 23 | + # Validate string structure |
| 24 | + if not isinstance(time_str, str): |
| 25 | + raise ValueError("Time must be a string") |
| 26 | + |
| 27 | + if len(time_str) != 8: |
| 28 | + raise ValueError(f"Invalid time length: '{time_str}' (expected 8 characters)") |
| 29 | + |
| 30 | + if time_str[2] != ":" or time_str[5] != ":": |
| 31 | + raise ValueError(f"Invalid format: '{time_str}' (use HH:MM:SS)") |
| 32 | + |
| 33 | + # Extract and validate components |
| 34 | + try: |
| 35 | + hours = int(time_str[0:2]) |
| 36 | + minutes = int(time_str[3:5]) |
| 37 | + seconds = int(time_str[6:8]) |
| 38 | + except ValueError as e: |
| 39 | + raise ValueError(f"Non-numeric components in '{time_str}': {e}") from e |
| 40 | + |
| 41 | + # Validate value ranges |
| 42 | + if not (0 <= hours < 24): |
| 43 | + raise ValueError(f"Hours out of range (0-23): {hours}") |
| 44 | + if not (0 <= minutes < 60): |
| 45 | + raise ValueError(f"Minutes out of range (0-59): {minutes}") |
| 46 | + if not (0 <= seconds < 60): |
| 47 | + raise ValueError(f"Seconds out of range (0-59): {seconds}") |
| 48 | + |
| 49 | + return hours, minutes, seconds |
| 50 | + |
| 51 | + |
| 52 | +def time_to_seconds(hours: int, minutes: int, seconds: int) -> int: |
| 53 | + """Convert hours, minutes, seconds to total seconds since midnight. |
| 54 | +
|
| 55 | + Args: |
| 56 | + hours: Hours (0-23) |
| 57 | + minutes: Minutes (0-59) |
| 58 | + seconds: Seconds (0-59) |
| 59 | +
|
| 60 | + Returns: |
| 61 | + Total seconds (0-86399). |
| 62 | + """ |
| 63 | + # Double-check input ranges (defensive programming) |
| 64 | + if not (0 <= hours < 24): |
| 65 | + raise ValueError(f"Invalid hours: {hours} (must be 0-23)") |
| 66 | + if not (0 <= minutes < 60): |
| 67 | + raise ValueError(f"Invalid minutes: {minutes} (must be 0-59)") |
| 68 | + if not (0 <= seconds < 60): |
| 69 | + raise ValueError(f"Invalid seconds: {seconds} (must be 0-59)") |
| 70 | + |
| 71 | + return hours * 3600 + minutes * 60 + seconds |
| 72 | + |
| 73 | + |
| 74 | +def seconds_to_time(total_seconds: int) -> tuple[int, int, int]: |
| 75 | + """Convert total seconds to hours, minutes, seconds. |
| 76 | +
|
| 77 | + Args: |
| 78 | + total_seconds: Total seconds (handles negative values and large numbers). |
| 79 | +
|
| 80 | + Returns: |
| 81 | + Tuple containing (hours, minutes, seconds) normalized to 0-23:59:59. |
| 82 | + """ |
| 83 | + # Handle negative values by adding full days until positive |
| 84 | + if total_seconds < 0: |
| 85 | + days_to_add = (-total_seconds // 86400) + 1 |
| 86 | + total_seconds += days_to_add * 86400 |
| 87 | + |
| 88 | + # Normalize to within a single day (0-86399 seconds) |
| 89 | + total_seconds %= 86400 |
| 90 | + |
| 91 | + hours = total_seconds // 3600 |
| 92 | + remaining = total_seconds % 3600 |
| 93 | + minutes = remaining // 60 |
| 94 | + seconds = remaining % 60 |
| 95 | + |
| 96 | + return hours, minutes, seconds |
| 97 | + |
| 98 | + |
| 99 | +def format_time(hours: int, minutes: int, seconds: int) -> str: |
| 100 | + """Format hours, minutes, seconds into HH:MM:SS string. |
| 101 | +
|
| 102 | + Args: |
| 103 | + hours: Hours (0-23) |
| 104 | + minutes: Minutes (0-59) |
| 105 | + seconds: Seconds (0-59) |
| 106 | +
|
| 107 | + Returns: |
| 108 | + Formatted time string with leading zeros where necessary. |
| 109 | + """ |
| 110 | + # Final validation before formatting |
| 111 | + if not (0 <= hours < 24): |
| 112 | + raise ValueError(f"Invalid hours for formatting: {hours}") |
| 113 | + if not (0 <= minutes < 60): |
| 114 | + raise ValueError(f"Invalid minutes for formatting: {minutes}") |
| 115 | + if not (0 <= seconds < 60): |
| 116 | + raise ValueError(f"Invalid seconds for formatting: {seconds}") |
| 117 | + |
| 118 | + return f"{hours:02d}:{minutes:02d}:{seconds:02d}" |
| 119 | + |
| 120 | + |
| 121 | +def calculate_time_difference(t1: str, t2: str) -> str: |
| 122 | + """Calculate the time difference between two times (t2 - t1). |
| 123 | +
|
| 124 | + Args: |
| 125 | + t1: Start time in HH:MM:SS format. |
| 126 | + t2: End time in HH:MM:SS format. |
| 127 | +
|
| 128 | + Returns: |
| 129 | + Time difference in HH:MM:SS format. |
| 130 | + """ |
| 131 | + # Validate input isn't empty |
| 132 | + if not t1.strip(): |
| 133 | + raise ValueError("Initial time cannot be empty") |
| 134 | + if not t2.strip(): |
| 135 | + raise ValueError("Final time cannot be empty") |
| 136 | + |
| 137 | + # Parse input times with detailed error context |
| 138 | + try: |
| 139 | + h1, m1, s1 = parse_time(t1) |
| 140 | + except ValueError as e: |
| 141 | + raise ValueError(f"Invalid initial time: {e}") from e |
| 142 | + |
| 143 | + try: |
| 144 | + h2, m2, s2 = parse_time(t2) |
| 145 | + except ValueError as e: |
| 146 | + raise ValueError(f"Invalid final time: {e}") from e |
| 147 | + |
| 148 | + # Convert to total seconds with range checks |
| 149 | + sec1 = time_to_seconds(h1, m1, s1) |
| 150 | + sec2 = time_to_seconds(h2, m2, s2) |
| 151 | + |
| 152 | + # Calculate difference (handle midnight crossing) |
| 153 | + diff_seconds = sec2 - sec1 |
| 154 | + |
| 155 | + # Convert back to hours, minutes, seconds with normalization |
| 156 | + h_diff, m_diff, s_diff = seconds_to_time(diff_seconds) |
| 157 | + |
| 158 | + # Format and return result |
| 159 | + return format_time(h_diff, m_diff, s_diff) |
| 160 | + |
| 161 | + |
| 162 | +def main() -> None: |
| 163 | + """Main function to handle user input and display results.""" |
| 164 | + try: |
| 165 | + t1 = input("Initial schedule (HH:MM:SS): ").strip() |
| 166 | + t2 = input("Final schedule (HH:MM:SS): ").strip() |
| 167 | + |
| 168 | + result = calculate_time_difference(t1, t2) |
| 169 | + print(f"Final result is: {result}") |
| 170 | + |
| 171 | + except ValueError as e: |
| 172 | + print(f"Error: {e}", file=sys.stderr) |
| 173 | + sys.exit(1) |
| 174 | + except Exception as e: |
| 175 | + print(f"Unexpected error: {e}", file=sys.stderr) |
| 176 | + sys.exit(1) |
| 177 | + |
| 178 | + |
| 179 | +if __name__ == "__main__": |
| 180 | + main() |
0 commit comments