Files
FastapiAdmin/backend/app/utils/time_util.py
T
zhangtao c2ca6d19ac refactor: 优化代码注释和文档字符串格式
style: 统一代码风格和格式

docs: 完善函数和方法的文档字符串

refactor(base_model): 移除冗余的表名和表参数生成方法

refactor(constant): 更新返回码注释格式

refactor(router_class): 添加路由处理器的详细文档

refactor(database): 完善数据库连接函数的文档

refactor(security): 添加认证类和方法的详细文档

refactor(validator): 更新验证器函数的文档格式

refactor(serialize): 优化序列化工具类的文档

refactor(response): 完善响应类的文档字符串

refactor(dependencies): 添加依赖函数的详细文档

refactor(initialize): 完善初始化脚本的文档

refactor(plugin): 添加生命周期和中间件注册的文档

refactor(service): 完善服务层方法的文档

refactor(controller): 添加控制器方法的详细文档

refactor(crud): 完善CRUD操作的文档字符串

refactor(schema): 简化模型类并移除冗余字段

refactor(param): 更新查询参数类的注释格式

refactor(template): 优化代码生成模板的格式

refactor(console): 添加控制台输出功能的实现

refactor(util): 完善工具函数的文档字符串
2025-10-18 16:31:28 +08:00

282 lines
8.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
import re
from datetime import datetime
from typing import Any, List, Dict
class TimeUtil:
"""
时间格式化工具类
"""
DEFAULT_DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
@classmethod
def object_format_datetime(cls, obj: Any) -> Any:
"""
格式化对象中的 datetime 属性为默认字符串格式。
参数:
- obj (Any): 输入对象。
返回:
- Any: 格式化后的对象。
"""
for attr in dir(obj):
if not attr.startswith('_'): # 跳过私有属性
value = getattr(obj, attr)
if isinstance(value, datetime):
setattr(obj, attr, value.strftime(cls.DEFAULT_DATETIME_FORMAT))
return obj
@classmethod
def list_format_datetime(cls, lst: List[Any]) -> List[Any]:
"""
格式化列表内每个对象的 datetime 属性。
参数:
- lst (List[Any]): 对象列表。
返回:
- List[Any]: 格式化后的对象列表。
"""
return [cls.object_format_datetime(obj) for obj in lst]
@classmethod
def format_datetime_dict_list(cls, dicts: List[Dict]) -> List[Dict]:
"""
递归格式化字典列表中的 datetime 值为默认字符串格式。
参数:
- dicts (List[Dict]): 字典列表。
返回:
- List[Dict]: 格式化后的字典列表。
"""
def _format_value(value: Any) -> Any:
if isinstance(value, dict):
return {k: _format_value(v) for k, v in value.items()}
elif isinstance(value, list):
return [_format_value(item) for item in value]
elif isinstance(value, datetime):
return value.strftime(cls.DEFAULT_DATETIME_FORMAT)
return value
return [_format_value(item) for item in dicts]
@classmethod
def __valid_range(cls, search_str: str, start_range: int, end_range: int) -> bool:
"""
校验范围字符串是否合法。
参数:
- search_str (str): 范围字符串(例如:"1-5")。
- start_range (int): 允许的最小范围值。
- end_range (int): 允许的最大范围值。
返回:
- bool: 校验是否通过。
"""
match = re.match(r'^(\d+)-(\d+)$', search_str)
if match:
start, end = int(match.group(1)), int(match.group(2))
return start_range <= start < end <= end_range
return False
@classmethod
def __valid_sum(cls, search_str: str, start_range_a: int, start_range_b: int, end_range_a: int, end_range_b: int, sum_range: int) -> bool:
"""
校验和字符串是否合法。
参数:
- search_str (str): 和字符串(例如:"1/5")。
- start_range_a (int): 允许的最小范围值A。
- start_range_b (int): 允许的最大范围值A。
- end_range_a (int): 允许的最小范围值B。
- end_range_b (int): 允许的最大范围值B。
- sum_range (int): 允许的最大和值。
返回:
- bool: 校验是否通过。
"""
match = re.match(r'^(\d+)/(\d+)$', search_str)
if match:
start, end = int(match.group(1)), int(match.group(2))
return (
start_range_a <= start <= start_range_b
and end_range_a <= end <= end_range_b
and start + end <= sum_range
)
return False
@classmethod
def validate_second_or_minute(cls, second_or_minute: str):
"""
校验秒或分钟字段的合法性。
参数:
- second_or_minute (str): 秒或分钟值。
返回:
- bool: 校验是否通过。
"""
if (
second_or_minute == '*'
or ('-' in second_or_minute and cls.__valid_range(second_or_minute, 0, 59))
or ('/' in second_or_minute and cls.__valid_sum(second_or_minute, 0, 58, 1, 59, 59))
or re.match(r'^(?:[0-5]?\d|59)(?:,[0-5]?\d|59)*$', second_or_minute)
):
return True
return False
@classmethod
def validate_hour(cls, hour: str):
"""
校验小时字段的合法性。
参数:
- hour (str): 小时值。
返回:
- bool: 校验是否通过。
"""
if (
hour == '*'
or ('-' in hour and cls.__valid_range(hour, 0, 23))
or ('/' in hour and cls.__valid_sum(hour, 0, 22, 1, 23, 23))
or re.match(r'^(?:0|[1-9]|1\d|2[0-3])(?:,(?:0|[1-9]|1\d|2[0-3]))*$', hour)
):
return True
return False
@classmethod
def validate_day(cls, day: str):
"""
校验日期字段的合法性。
参数:
- day (str): 日值。
返回:
- bool: 校验是否通过。
"""
if (
day in ['*', '?', 'L']
or ('-' in day and cls.__valid_range(day, 1, 31))
or ('/' in day and cls.__valid_sum(day, 1, 30, 1, 30, 31))
or ('W' in day and re.match(r'^(?:[1-9]|1\d|2\d|3[01])W$', day))
or re.match(r'^(?:0|[1-9]|1\d|2[0-9]|3[0-1])(?:,(?:0|[1-9]|1\d|2[0-9]|3[0-1]))*$', day)
):
return True
return False
@classmethod
def validate_month(cls, month: str):
"""
校验月份字段的合法性。
参数:
- month (str): 月值。
返回:
- bool: 校验是否通过。
"""
if (
month == '*'
or ('-' in month and cls.__valid_range(month, 1, 12))
or ('/' in month and cls.__valid_sum(month, 1, 11, 1, 11, 12))
or re.match(r'^(?:0|[1-9]|1[0-2])(?:,(?:0|[1-9]|1[0-2]))*$', month)
):
return True
return False
@classmethod
def validate_week(cls, week: str):
"""
校验星期字段的合法性。
参数:
- week (str): 周值。
返回:
- bool: 校验是否通过。
"""
if (
week in ['*', '?']
or ('-' in week and cls.__valid_range(week, 1, 7))
or ('#' in week and re.match(r'^[1-7]#[1-4]$', week))
or ('L' in week and re.match(r'^[1-7]L$', week))
or re.match(r'^[1-7](?:(,[1-7]))*$', week)
):
return True
return False
@classmethod
def validate_year(cls, year: str):
"""
校验年份字段的合法性。
参数:
- year (str): 年值。
返回:
- bool: 校验是否通过。
"""
current_year = int(datetime.now().year)
future_years = [current_year + i for i in range(9)]
if (
year == '*'
or ('-' in year and cls.__valid_range(year, current_year, 2099))
or ('/' in year and cls.__valid_sum(year, current_year, 2098, 1, 2099 - current_year, 2099))
or ('#' in year and re.match(r'^[1-7]#[1-4]$', year))
or ('L' in year and re.match(r'^[1-7]L$', year))
or (
(len(year) == 4 or ',' in year)
and all(int(item) in future_years and current_year <= int(item) <= 2099 for item in year.split(','))
)
):
return True
return False
@classmethod
def validate_cron_expression(cls, cron_expression: str):
"""
校验 Cron 表达式是否正确。
* * * * * *
| | | | | |
| | | | | +--- 星期(0-70和7都表示星期日)
| | | | +----- 月份(1-12
| | | +------- 日期(1-31
| | +--------- 小时(0-23
| +----------- 分钟(0-59
+------------- 秒(0-59),部分环境不支持秒字段。
参数:
- cron_expression (str): Cron 表达式。
返回:
- bool: 校验是否通过。
"""
values = cron_expression.split()
if len(values) != 6 and len(values) != 7:
return False
second_validation = cls.validate_second_or_minute(values[0])
minute_validation = cls.validate_second_or_minute(values[1])
hour_validation = cls.validate_hour(values[2])
day_validation = cls.validate_day(values[3])
month_validation = cls.validate_month(values[4])
week_validation = cls.validate_week(values[5])
validation = (
second_validation
and minute_validation
and hour_validation
and day_validation
and month_validation
and week_validation
)
if len(values) == 6:
return validation
if len(values) == 7:
year_validation = cls.validate_year(values[6])
return validation and year_validation