-
Notifications
You must be signed in to change notification settings - Fork 3
/
time_tools.py
120 lines (94 loc) · 3.5 KB
/
time_tools.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import dataclasses
import datetime
import pytz
import random
from config import DATE_FROM, TIME_ZONE
from datetime import timedelta
from random import randrange
from russian import (
day_in_nominative, enumerate_items_to_string, hour_in_nominative, hour_in_genitive,
minute_in_genitive, minute_in_nominative,
number_to_russian, normilize_word,
)
@dataclasses.dataclass
class TranslateOption:
"""
Possible option to represent datetime and weight to pick this datetime
"""
value: str
weight: float = dataclasses.field(default=1, compare=False)
T = TranslateOption
def random_date(start, end):
"""
This function will return a random datetime between two datetime
objects.
"""
delta = end - start
int_delta = (delta.days * 24 * 60 * 60) + delta.seconds
random_second = randrange(int_delta)
return start + timedelta(seconds=random_second)
def _generate_translate_options(date: datetime.datetime):
"""
Generate possible options to represent datetime.
"""
hour, minute = date.hour, date.minute
hour_word = hour_in_nominative(hour)
single_hour_word = hour_in_nominative(hour, only_number=True)
minute_word = minute_in_nominative(minute)
single_minute_word = minute_in_nominative(minute, only_number=True)
if minute == 0:
yield T(f"ровно {hour_word}", 20)
elif minute == 30 and hour % 12 != 0:
yield T(f"пол {hour_in_genitive(hour % 12 + 1)}", 20)
elif hour == 0:
if minute == 0:
yield T("ровно полночь", 20)
else:
yield T(f"{minute_word} после полуночи", 10)
elif hour == 12:
if minute == 0:
yield T("ровно полдень", 20)
else:
yield T(f"{minute_word} после полудня", 10)
else:
# 'Без' mode
if minute >= 45:
if minute == 45:
yield T(f"без четверти {hour_in_nominative(hour + 1, only_number=True)}", 10)
yield T(f"без {minute_in_genitive(60 - minute)} минут {hour_in_nominative(hour + 1, only_number=True)}", 5)
if 1 <= minute <= 9:
yield T(f"{single_hour_word} ноль {single_minute_word}", 6)
if minute % 10 == 0:
yield T(' '.join([single_hour_word, single_minute_word]), 8)
yield T(' '.join([hour_word, minute_word]), 1)
def translate_time(date: datetime.datetime) -> str:
options = list(_generate_translate_options(date))
return random.choices(
population=[o.value for o in options],
weights=[o.weight for o in options],
k=1,
)[0]
def get_now() -> datetime.datetime:
return datetime.datetime.now(
pytz.timezone(TIME_ZONE)
)
def get_current_time_in_words():
now = get_now()
try:
return translate_time(now)
except:
return now.strftime("%H %M")
def translate_time_delta(delta: datetime.timedelta) -> str:
minutes = (delta.seconds // 60) % 60
hours = (delta.seconds // 3600) % 24
days = delta.days
res = []
if days > 0:
res.append(day_in_nominative(days))
if hours > 0:
res.append(number_to_russian(hours) + normilize_word(hours, ' час', ' часа', ' часов'))
if minutes > 0:
res.append(minute_in_nominative(minutes))
return enumerate_items_to_string(res, join_word='и')
def get_passed_time_in_words(date_from: datetime.datetime = DATE_FROM) -> str:
return translate_time_delta(get_now() - date_from)