def year_mon_for_check(year, week):
"""通过年周获取当前月,按每周最后一天的月份比对(最后一天为周日)"""
end_year_week = str(year) + '-' + str(week) + '-' + '0'
end_week_result = time.strptime(end_year_week, '%Y-%W-%w')
return int(end_week_result.tm_mon)
def get_num_week(year, week):
"""
:param year: 哪一年
:param week: 哪一周
通过几几年的第几周 获取某一周的周一和周日的时间 格式例:2021-12-27 年-月-日
一年有【0-52】周 周范围【0-6】0为周日 1-6 周一 ~ 周六
周一为每周的第一天
周日为每周的最后一天
"""
start_year_week = str(year) + '-' + str(week) + '-' + '1'
end_year_week = str(year) + '-' + str(week) + '-' + '0'
start_week_result = time.strptime(start_year_week, '%Y-%W-%w')
end_week_result = time.strptime(end_year_week, '%Y-%W-%w')
start_week_date = str(start_week_result.tm_year) + '-' + str(start_week_result.tm_mon) + '-' + str(start_week_result.tm_mday)
end_week_date = str(end_week_result.tm_year) + '-' + str(end_week_result.tm_mon) + '-' + str(end_week_result.tm_mday)
return start_week_date, end_week_date
def get_year_week(week_time: str):
"""
获取日期所处年,周(加不可为未来的日期)
:param week_time: 2002-01-02格式
"""
week_year, week_num, __ = datetime.date(*map(int, week_time.split('-'))).isocalendar()
week_mon = int(week_time.split('-')[1])
now_time = datetime.datetime.now() + datetime.timedelta(hours=8)
"""增加周数判断,不能创建未来周报"""
now_year, now_week, __ = now_time.isocalendar()
if week_num > now_week and week_year >= now_year:
raise ValueError("无法创建此工时,不可创建未来日期的工时")
return week_year, week_num, week_mon
函数功能解析
year_mon_for_check(year, week)
- 作用: 根据年份和周数计算该周最后一天(周日)对应的月份。
- 参数:
year: 年份(如2023)week: 周数(0-52)
- 返回值: 整数形式的月份(1-12)。
- 逻辑:
- 构造字符串格式为
年-周-周日标识(如2023-25-0)。 - 使用
time.strptime解析时间,返回月份值。
get_num_week(year, week)
- 作用: 获取指定年份和周数的周一与周日日期。
- 参数:
- 返回值: 元组
(start_week_date, end_week_date),格式为年-月-日。 - 逻辑:
- 周一通过
年-周-1标识,周日通过年-周-0标识。 - 解析后拼接年月日,返回格式化字符串。
get_year_week(week_time: str)
- 作用: 根据日期字符串获取其对应的年份、周数及月份,并校验是否为未来日期。
- 参数:
week_time: 日期字符串(如2002-01-02)。
- 返回值: 元组
(week_year, week_num, week_mon)。 - 逻辑:
- 使用
isocalendar()获取年份和周数。 - 校验周数是否超过当前周数(避免未来日期),若超限抛出异常。
注意事项
- 周数范围: 周数从0开始(部分系统可能从1开始),需确认实际业务需求。
- 时区处理:
now_time手动增加8小时(东八区),建议使用标准时区库(如pytz)。 - 跨年周: 年末周可能跨年(如2023年第52周跨越到2024年),需额外处理。
代码优化建议
import datetime
import time
def validate_future_date(week_year: int, week_num: int) -> None:
"""校验是否为未来周"""
current_year, current_week, _ = datetime.datetime.now().isocalendar()
if (week_year, week_num) > (current_year, current_week):
raise ValueError("禁止创建未来日期的工时")