Как правильно реализовать функцию обнуления времени?
Есть функция, которая переводит введённое время в секунды, используя модуль time:
def set_time(
Y=localtime(time())[0],
m=localtime(time())[1],
d=localtime(time())[2],
H=localtime(time())[3],
M=localtime(time())[4],
S=localtime(time())[5]):
Y_f = Y
m_f = m
d_f = d
H_f = H
M_f = M
S_f = S
formats = f"%Y-%m-%d %H:%M:%S"
date_format = f'{Y_f}-{m_f}-{d_f} {H_f}:{M_f}:{S_f}'
print(date_format)
date_format_struct = strptime(date_format, formats)
date_format_like_seconds_f = mktime(date_format_struct)
return date_format_like_seconds_f
У пользователя есть возможность вводить не все параметры - в этом случае в не введённые параметры устанавливаются значения по умолчанию. И никаких проблем нет, если заполнены все параметры с правого края, например:
set_time(H=15, M=10, S=10)
#Вывод : 2025-1-8 15:10:10
Однако тогда, если пользователь введёт только часы к примеру, то время справа от параметра часа будет установлено на таковое во время срабатывания функции, что недопустимо.
set_time(H=15)
#Вывод : 2025-1-8 15:19:2
Я пытаюсь сделать так, чтобы время справа от введённых параметров обнулялось, то есть становилось равным '00', либо '01', а время слева от введённых параметров всегда устанавливалось на настоящее время. То есть при вводе set_time(H=15), параметры M и S будут равны '00', а параметры d, m, Y будут равны настоящему времени. Я реализовал следующее решение с использованием match/case :
def set_time(
Y=localtime(time())[0],
m=localtime(time())[1],
d=localtime(time())[2],
H=localtime(time())[3],
M=localtime(time())[4],
S=localtime(time())[5]):
Y_f = Y
m_f = m
d_f = d
H_f = H
M_f = M
S_f = S
YYf = localtime(time())[0] == Y_f
mmf = localtime(time())[1] == m_f
ddf = localtime(time())[2] == d_f
HHf = localtime(time())[3] == H_f
MMf = localtime(time())[4] == M_f
SSf = localtime(time())[5] == S_f
print(YYf, mmf, ddf, HHf, MMf, SSf)
match YYf, mmf, ddf, HHf, MMf, SSf:
case True, True, True, True, False, True:
S_f = '00'
print('Минуты ')
case True, True, True, False, False, True:
S_f = '00'
print('Минуты ')
case True, True, False, False, False, True:
S_f = '00'
print('Минуты ')
case True, False, False, False, False, True:
S_f = '00'
print('Минуты ')
case False, False, False, False, False, True:
S_f = '00'
print('Минуты')
case True, True, True, False, True, True:
print('Часы ')
M_f = '00'
S_f = '00'
case True, True, False, False, True, True:
print('Часы ')
M_f = '00'
S_f = '00'
case True, False, False, False, True, True:
print('Часы ')
M_f = '00'
S_f = '00'
case False, False, False, False, True, True:
print('Часы ')
M_f = '00'
S_f = '00'
case True, True, False, True, True, True:
print('Дни ')
H_f = '00'
M_f = '00'
S_f = '00'
case True, False, False, True, True, True:
print('Дни ')
H_f = '00'
M_f = '00'
S_f = '00'
case False, False, False, True, True, True:
print('Дни ')
H_f = '00'
M_f = '00'
S_f = '00'
case True, False, True, True, True, True:
print('Месяцы ')
d_f = '01'
H_f = '00'
M_f = '00'
S_f = '00'
case False, False, True, True, True, True:
print('Месяцы ')
d_f = '01'
H_f = '00'
M_f = '00'
S_f = '00'
case False, True, True, True, True, True:
print('Года ')
m_f = '01'
d_f = '01'
H_f = '00'
M_f = '00'
S_f = '00'
formats = f"%Y-%m-%d %H:%M:%S"
date_format = f'{Y_f}-{m_f}-{d_f} {H_f}:{M_f}:{S_f}'
print(date_format)
date_format_struct = strptime(date_format, formats)
date_format_like_seconds_f = mktime(date_format_struct)
return date_format_like_seconds_f
Но у него есть недостаток - если запустить функцию в совпадающие временные точки выражение match будет не верным и выберется неверный case. Например, если запустить функцию в 21:24, предварительно введя параметры H=21, M=24, то случай в match будет эквивалентен True, True, True, True, True, True, в результате чего не найдётся ни одного совпадения. Буду благодарен, если подскажите как правильно решить эту задачу) По идее, если бы был способ разделить реагирование на пользовательский ввод параметров и реагирование на установку параметров по умолчанию, все было бы проще, но я такого метода не знаю.
PS:
Переформулировал условие из ответа @DiHASTRO, что будет работать корректно(см. комментарии в коде):
from time import *
def set_time(
Y=None,
m=None,
d=None,
H=None,
M=None,
S=None,
):
TIME_PARAMS_COUNT = 6
TIME_PARAMS_MINIMUMS = ['0000', '01', '01', '00', '00', '00']
time_params = [Y, m, d, H, M, S]
if time_params == [None, None, None, None, None, None]:
time_params = [localtime(time())[0], localtime(time())[1], localtime(time())[2], localtime(time())[3],
localtime(time())[4], localtime(time())[5]]
was_time_param_set = False
for i in range(TIME_PARAMS_COUNT - 1, -1, -1):
# 3) вхождение
if was_time_param_set is True:
while time_params[i] is None:
time_params[i] = localtime(time())[i]
# 2) второе вхождение
if time_params[i] is not None:
was_time_param_set = True
# 1) первое вхождение
while time_params[i] is None and was_time_param_set is False:
time_params[i] = TIME_PARAMS_MINIMUMS[i]
# Алгоритм следующий, происходит последовательная итерация по TIME_PARAMS_COUNT. ( 1) вхождение )Пока значения в time_params[i] is None и was_time_param_set is False
# time_params[i] обнуляется. Как только в в одной из итераций time_params[i] становится не равен None(то есть мы натыкаемся на введённые параметры), ключ was_time_param_set
# переключается на True( 2) вхождение). Введённые параметры при итерации по ним никак не изменяются. Происходит ( 3) вхождение ) в котором цикл while изменяет на localtime(time())[i]
# параметры после введённых, равные None.
formats = f"%Y-%m-%d %H:%M:%S"
Y_f, m_f, d_f, H_f, M_f, S_f = time_params
date_format = f'{Y_f}-{m_f}-{d_f} {H_f}:{M_f}:{S_f}'
print(date_format)
date_format_struct = strptime(date_format, formats)
date_format_like_seconds_f = mktime(date_format_struct)
return date_format_like_seconds_f
if __name__ == '__main__':
set_time(H=18, M=45, S=21)
set_time(M=45, S=21)
set_time(S=21)
set_time()
set_time(H=18)
set_time(H=18, M=45)
#Вывод:
# 2025-1-9 18:45:21
# 2025-1-9 21:45:21
# 2025-1-9 21:3:21
# 2025-1-9 21:3:2
# 2025-1-9 18:00:00
# 2025-1-9 18:45:00
Ответы (2 шт):
Честно не совсем понимаю, зачем вы использовали match-case, всё гораздо проще решается.
from time import *
def set_time(
Y=None, # Выставляем все параметры по умолчанию изначально None,
m=None, # так как у нас по сути параметры по умолчанию разные, в
d=None, # зависимости от других параметров, а с None сравнивать в
H=None, # таком случае - база
M=None,
S=None,
):
TIME_PARAMS_COUNT = 6 # количество параметров, описывающих время (надо для цикла)
TIME_PARAMS_MINIMUMS = ['0000', '01', '01', '00', '00', '00'] # нулевые значения у каждого параметра разные, лучше запишем в константу
time_params = [Y, m, d, H, M, S] # формируем массив из параметров, по которому будем итерироваться
was_time_param_set = False # дошёл ли цикл до крайнего правого имеющегося значения
# смысл алгоритма в следующем: итерируемся справа налево по массиву (точнее итерируемся
# по индексу), и пока у нас переданный параметр None, мы записываем туда "нулевое" значение
# по умолчанию (например, для минут - "00", для дней - "01" и т.д.)
# когда мы получаем элемент какой-то, который в параметрах не None, вместо "нулевых"
# значений, начинаем вписывать localtime(time())[...], если значение не передано
# (маркером того, что мы дошли до ненулевого значения, является переменная was_time_param_set)
for i in range(TIME_PARAMS_COUNT - 1, -1, -1):
if was_time_param_set and not time_params[i]:
time_params[i] = localtime(time())[i]
elif time_params[i] is None:
time_params[i] = TIME_PARAMS_MINIMUMS[i]
was_time_param_set = True
formats = f"%Y-%m-%d %H:%M:%S"
Y_f, m_f, d_f, H_f, M_f, S_f = time_params
date_format = f'{Y_f}-{m_f}-{d_f} {H_f}:{M_f}:{S_f}'
print(date_format)
date_format_struct = strptime(date_format, formats)
date_format_like_seconds_f = mktime(date_format_struct)
return date_format_like_seconds_f
if __name__ == '__main__':
set_time(H=18, M=45, S=21)
set_time(M=45, S=21)
set_time(S=21)
set_time()
set_time(H=18)
set_time(H=18, M=45)
# Вывод:
# 2025-1-01 18:45:21
# 2025-1-9 00:45:21
# 2025-1-9 20:00:21
# 2025-1-9 20:50:00
# 2025-1-9 18:50:00
# 2025-1-9 18:45:00
Если верно уловил ваши мысли:
from time import localtime, time, strptime, mktime
def set_time(Y=None, m=None, d=None, H=None, M=None, S=None):
now = localtime(time())
Y = now.tm_year if Y is None else Y
m = now.tm_mon if m is None else m
d = now.tm_mday if d is None else d
H = 0 if not any([H, M, S]) else now[3] if H is None else H
M = 0 if not any([M, S]) else now[4] if M is None else M
S = 0 if S is None else S
formats = "%Y-%m-%d %H:%M:%S"
date_format = f"{Y}-{m:02d}-{d:02d} {H:02d}:{M:02d}:{S:02d}"
print(date_format)
date_format_struct = strptime(date_format, formats)
date_format_like_seconds_f = mktime(date_format_struct)
return date_format_like_seconds_f
set_time(H=18, M=45, S=21)
set_time(M=45, S=21)
set_time(S=21)
set_time()
set_time(H=18)
set_time(H=18, M=45)
Вывод:
2025-01-09 18:45:21
2025-01-09 20:45:21
2025-01-09 20:24:21
2025-01-09 00:00:00
2025-01-09 18:00:00
2025-01-09 18:45:00
[Program finished]