diff --git a/email_service.py b/email_service.py index a070cee..a4289cf 100644 --- a/email_service.py +++ b/email_service.py @@ -33,6 +33,24 @@ import db_pool from crypto_utils import encrypt_password, decrypt_password, is_encrypted +def parse_datetime(dt_str: str) -> datetime: + """解析数据库中的时间字符串,支持带微秒和不带微秒的格式""" + if not dt_str: + return datetime.min + # 尝试多种格式 + formats = [ + '%Y-%m-%d %H:%M:%S.%f', # 带微秒 + '%Y-%m-%d %H:%M:%S', # 不带微秒 + ] + for fmt in formats: + try: + return datetime.strptime(dt_str, fmt) + except ValueError: + continue + # 如果都失败,返回最小时间(视为过期) + return datetime.min + + # ============ 常量配置 ============ # 邮件类型 @@ -1062,7 +1080,7 @@ def verify_email_token(token: str, token_type: str) -> Optional[Dict[str, Any]]: return None # 检查是否过期 - if datetime.strptime(expires_at, '%Y-%m-%d %H:%M:%S') < datetime.now(): + if parse_datetime(expires_at) < datetime.now(): return None # 标记为已使用 @@ -1100,7 +1118,7 @@ def check_rate_limit(email: str, token_type: str) -> bool: if not row: return True - last_sent = datetime.strptime(row[0], '%Y-%m-%d %H:%M:%S') + last_sent = parse_datetime(row[0]) elapsed = (datetime.now() - last_sent).total_seconds() return elapsed >= limit_seconds @@ -1376,7 +1394,7 @@ def verify_password_reset_token(token: str) -> Optional[Dict[str, Any]]: return None # 检查是否过期 - if datetime.strptime(expires_at, '%Y-%m-%d %H:%M:%S') < datetime.now(): + if parse_datetime(expires_at) < datetime.now(): return None return {'user_id': user_id, 'email': email, 'token_id': token_id}