You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.1 KiB

"""
日期工具模块
"""
from datetime import date, datetime, timedelta
from typing import List, Optional
def parse_date(date_str: str) -> date:
"""解析日期字符串 (YYYYMMDD 或 YYYY-MM-DD)"""
if len(date_str) == 8:
return datetime.strptime(date_str, "%Y%m%d").date()
elif len(date_str) == 10:
return datetime.strptime(date_str, "%Y-%m-%d").date()
else:
raise ValueError(f"无效的日期格式: {date_str}")
def format_date(d: date, format_str: str = "%Y-%m-%d") -> str:
"""格式化日期"""
return d.strftime(format_str)
def format_datetime(dt: datetime, format_str: str = "%Y-%m-%d %H:%M:%S") -> str:
"""格式化日期时间"""
return dt.strftime(format_str)
def get_market_from_code(code: str) -> str:
"""从代码获取市场"""
if code.endswith(".SH"):
return "SH"
elif code.endswith(".SZ"):
return "SZ"
elif code.endswith(".BJ"):
return "BJ"
elif code.endswith(".CFE"):
return "CFE"
else:
return "SH" # 默认上海
def get_trading_days_between(
start_date: date,
end_date: date,
calendar: Optional[List[date]] = None
) -> List[date]:
"""获取两个日期之间的交易日列表"""
if calendar:
return [d for d in calendar if start_date <= d <= end_date]
# 如果没有提供交易日历,简单排除周末
trading_days = []
current = start_date
while current <= end_date:
if current.weekday() < 5: # 周一到周五
trading_days.append(current)
current += timedelta(days=1)
return trading_days
def get_default_date_range(days: int = 365) -> tuple:
"""获取默认日期范围"""
end_date = date.today()
start_date = end_date - timedelta(days=days)
return start_date, end_date
def int_to_date(date_int: int) -> date:
"""将整数日期(YYYYMMDD)转换为date对象"""
return datetime.strptime(str(date_int), "%Y%m%d").date()
def date_to_int(d: date) -> int:
"""将date对象转换为整数日期(YYYYMMDD)"""
return int(d.strftime("%Y%m%d"))