e_lib.time_utils
Time formatting helpers.
format_time renders a number of seconds as a human-readable Russian string
and is used e.g. by e_lib.assistants.ScheduledAssistant.
1# -*- coding: utf-8 -*- 2"""e_lib.time_utils 3 4Time formatting helpers. 5 6``format_time`` renders a number of seconds as a human-readable Russian string 7and is used e.g. by :class:`e_lib.assistants.ScheduledAssistant`. 8""" 9 10from __future__ import annotations 11 12from datetime import datetime, timedelta 13 14 15def format_time(seconds: int) -> str: 16 """Format seconds as a human-readable Russian string. 17 18 Zero-valued units are omitted. Supports correct plural forms 19 (день/дня/дней, час/часа/часов, минута/минуты/минут, etc.). 20 21 Args: 22 seconds: Number of seconds. 23 24 Returns: 25 Formatted string, e.g. "2 часа 30 минут", or "0 секунд" for 26 non-positive values. 27 """ 28 if seconds < 0: 29 return "0 секунд" 30 31 intervals = [("день", 86400), ("час", 3600), ("минуту", 60), ("секунду", 1)] 32 33 parts = [] 34 35 for name, count in intervals: 36 if seconds >= count: 37 value = seconds // count 38 seconds %= count 39 40 # Skip zero values. 41 if value == 0: 42 continue 43 44 # Correct plural forms. 45 if name == "день": 46 if value % 10 == 1 and value % 100 != 11: 47 name = "день" 48 elif 2 <= value % 10 <= 4 and (value % 100 < 10 or value % 100 >= 20): 49 name = "дня" 50 else: 51 name = "дней" 52 elif name == "час": 53 if value % 10 == 1 and value % 100 != 11: 54 name = "час" 55 elif 2 <= value % 10 <= 4 and (value % 100 < 10 or value % 100 >= 20): 56 name = "часа" 57 else: 58 name = "часов" 59 elif name == "минуту": 60 if value % 10 == 1 and value % 100 != 11: 61 name = "минута" 62 elif 2 <= value % 10 <= 4 and (value % 100 < 10 or value % 100 >= 20): 63 name = "минуты" 64 else: 65 name = "минут" 66 elif name == "секунду": 67 if value % 10 == 1 and value % 100 != 11: 68 name = "секунда" 69 elif 2 <= value % 10 <= 4 and (value % 100 < 10 or value % 100 >= 20): 70 name = "секунды" 71 else: 72 name = "секунд" 73 74 parts.append(f"{int(value)} {name}") 75 76 if not parts: 77 return "0 секунд" 78 79 return " ".join(parts) 80 81 82def time_passed(seconds_ago: int) -> datetime: 83 """Return the datetime that is ``seconds_ago`` seconds in the past. 84 85 Args: 86 seconds_ago: Number of seconds to go back. 87 88 Returns: 89 A ``datetime`` computed from the current moment minus ``seconds_ago``. 90 """ 91 current_time = datetime.now() 92 target_time = current_time - timedelta(seconds=seconds_ago) 93 return target_time
def
format_time(seconds: int) -> str:
16def format_time(seconds: int) -> str: 17 """Format seconds as a human-readable Russian string. 18 19 Zero-valued units are omitted. Supports correct plural forms 20 (день/дня/дней, час/часа/часов, минута/минуты/минут, etc.). 21 22 Args: 23 seconds: Number of seconds. 24 25 Returns: 26 Formatted string, e.g. "2 часа 30 минут", or "0 секунд" for 27 non-positive values. 28 """ 29 if seconds < 0: 30 return "0 секунд" 31 32 intervals = [("день", 86400), ("час", 3600), ("минуту", 60), ("секунду", 1)] 33 34 parts = [] 35 36 for name, count in intervals: 37 if seconds >= count: 38 value = seconds // count 39 seconds %= count 40 41 # Skip zero values. 42 if value == 0: 43 continue 44 45 # Correct plural forms. 46 if name == "день": 47 if value % 10 == 1 and value % 100 != 11: 48 name = "день" 49 elif 2 <= value % 10 <= 4 and (value % 100 < 10 or value % 100 >= 20): 50 name = "дня" 51 else: 52 name = "дней" 53 elif name == "час": 54 if value % 10 == 1 and value % 100 != 11: 55 name = "час" 56 elif 2 <= value % 10 <= 4 and (value % 100 < 10 or value % 100 >= 20): 57 name = "часа" 58 else: 59 name = "часов" 60 elif name == "минуту": 61 if value % 10 == 1 and value % 100 != 11: 62 name = "минута" 63 elif 2 <= value % 10 <= 4 and (value % 100 < 10 or value % 100 >= 20): 64 name = "минуты" 65 else: 66 name = "минут" 67 elif name == "секунду": 68 if value % 10 == 1 and value % 100 != 11: 69 name = "секунда" 70 elif 2 <= value % 10 <= 4 and (value % 100 < 10 or value % 100 >= 20): 71 name = "секунды" 72 else: 73 name = "секунд" 74 75 parts.append(f"{int(value)} {name}") 76 77 if not parts: 78 return "0 секунд" 79 80 return " ".join(parts)
Format seconds as a human-readable Russian string.
Zero-valued units are omitted. Supports correct plural forms (день/дня/дней, час/часа/часов, минута/минуты/минут, etc.).
Args: seconds: Number of seconds.
Returns: Formatted string, e.g. "2 часа 30 минут", or "0 секунд" for non-positive values.
def
time_passed(seconds_ago: int) -> datetime.datetime:
83def time_passed(seconds_ago: int) -> datetime: 84 """Return the datetime that is ``seconds_ago`` seconds in the past. 85 86 Args: 87 seconds_ago: Number of seconds to go back. 88 89 Returns: 90 A ``datetime`` computed from the current moment minus ``seconds_ago``. 91 """ 92 current_time = datetime.now() 93 target_time = current_time - timedelta(seconds=seconds_ago) 94 return target_time
Return the datetime that is seconds_ago seconds in the past.
Args: seconds_ago: Number of seconds to go back.
Returns:
A datetime computed from the current moment minus seconds_ago.