Convert string with time units to seconds
This commit is contained in:
@@ -2,10 +2,19 @@
|
||||
Current timestamp strings and time zones
|
||||
"""
|
||||
|
||||
import re
|
||||
from datetime import datetime
|
||||
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||
|
||||
|
||||
class TimeParseError(Exception):
|
||||
"""Custom exception for time parsing errors."""
|
||||
|
||||
|
||||
class TimeUnitError(Exception):
|
||||
"""Custom exception for time parsing errors."""
|
||||
|
||||
|
||||
class TimestampStrings:
|
||||
"""
|
||||
set default time stamps
|
||||
@@ -24,3 +33,73 @@ class TimestampStrings:
|
||||
self.timestamp = self.timestamp_now.strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.timestamp_tz = self.timestamp_now_tz.strftime("%Y-%m-%d %H:%M:%S %Z")
|
||||
self.timestamp_file = self.timestamp_now.strftime("%Y-%m-%d_%H%M%S")
|
||||
|
||||
|
||||
def convert_to_seconds(time_string: str) -> int:
|
||||
"""
|
||||
Conver a string with time units into a seconds string
|
||||
The following units are allowed
|
||||
Y: 365 days
|
||||
M: 30 days
|
||||
d, h, m, s
|
||||
|
||||
Arguments:
|
||||
time_string {str} -- _description_
|
||||
|
||||
Raises:
|
||||
ValueError: _description_
|
||||
|
||||
Returns:
|
||||
int -- _description_
|
||||
"""
|
||||
|
||||
# Define time unit conversion factors
|
||||
unit_factors: dict[str, int] = {
|
||||
'Y': 31536000, # 365 days * 86400 seconds/day
|
||||
'M': 2592000 * 12, # 1 year in seconds (assuming 365 days per year)
|
||||
'd': 86400, # 1 day in seconds
|
||||
'h': 3600, # 1 hour in seconds
|
||||
'm': 60, # minutes to seconds
|
||||
's': 1 # 1 second in seconds
|
||||
}
|
||||
long_unit_names: dict[str, str] = {
|
||||
'year': 'Y',
|
||||
'years': 'Y',
|
||||
'month': 'M',
|
||||
'months': 'M',
|
||||
'day': 'd',
|
||||
'days': 'd',
|
||||
'hour': 'h',
|
||||
'hours': 'h',
|
||||
'minute': 'm',
|
||||
'minutes': 'm',
|
||||
'min': 'm',
|
||||
'second': 's',
|
||||
'seconds': 's',
|
||||
'sec': 's',
|
||||
}
|
||||
|
||||
total_seconds = 0
|
||||
|
||||
seen_units: list[str] = [] # Track units that have been encountered
|
||||
|
||||
# Use regex to match number and time unit pairs
|
||||
for match in re.finditer(r'(\d+)\s*([a-zA-Z]+)', time_string):
|
||||
value, unit = int(match.group(1)), match.group(2)
|
||||
|
||||
# full name check, fallback to original name
|
||||
unit = long_unit_names.get(unit.lower(), unit)
|
||||
|
||||
# Check for duplicate units
|
||||
if unit in seen_units:
|
||||
raise TimeParseError(f"Unit '{unit}' appears more than once.")
|
||||
# Check invalid unit
|
||||
if unit not in unit_factors:
|
||||
raise TimeUnitError(f"Unit '{unit}' is not a valid unit name.")
|
||||
# Add to total seconds based on the units
|
||||
if unit in unit_factors:
|
||||
total_seconds += value * unit_factors[unit]
|
||||
|
||||
seen_units.append(unit)
|
||||
|
||||
return total_seconds
|
||||
|
||||
47
test-run/string_handling/timestamp_strings.py
Normal file
47
test-run/string_handling/timestamp_strings.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
timestamp string checks
|
||||
"""
|
||||
|
||||
from corelibs.string_handling.timestamp_strings import convert_to_seconds, TimeParseError, TimeUnitError
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""
|
||||
Comment
|
||||
"""
|
||||
test_cases = [
|
||||
"5M 6d", # 5 months, 6 days
|
||||
"2h 30m 45s", # 2 hours, 30 minutes, 45 seconds
|
||||
"1Y 2M 3d", # 1 year, 2 months, 3 days
|
||||
"1h", # 1 hour
|
||||
"30m", # 30 minutes
|
||||
"2 hours 15 minutes", # 2 hours, 15 minutes
|
||||
"1d 12h", # 1 day, 12 hours
|
||||
"3M 2d 4h", # 3 months, 2 days, 4 hours
|
||||
"45s", # 45 seconds
|
||||
"1 year 2 months", # 1 year, 2 months
|
||||
"2Y 6M 15d 8h 30m 45s", # Complex example
|
||||
# ]
|
||||
# invalid_test_cases = [
|
||||
"5M 6d 2M", # months appears twice
|
||||
"2h 30m 45s 1h", # hours appears twice
|
||||
"1d 2 days", # days appears twice (short and long form)
|
||||
"30m 45 minutes", # minutes appears twice
|
||||
"1Y 2 years", # years appears twice
|
||||
"1x 2 yrs", # invalid names
|
||||
]
|
||||
|
||||
for time_string in test_cases:
|
||||
try:
|
||||
result = convert_to_seconds(time_string)
|
||||
print(f"{time_string} => {result}")
|
||||
except (TimeParseError, TimeUnitError) as e:
|
||||
print(f"Error encountered for {time_string}: {type(e).__name__}: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
# __END__
|
||||
Reference in New Issue
Block a user