datetime_demo · 时间处理演示 2026-09-27

内容:
基础:datetime / timedelta,字符串 2026-08-14 ↔ 时间 互转
与 pandas 联动:pd.to_datetime、按时间切片
冷知识:自然日 ≠ 交易日(行情数据自动跳过周末和节假日)

导入

from datetime import datetime, timedelta # from datetime import datetime, timedelta:从 datetime 包里拿两个东西 # datetime:一个时间点;timedelta:一段时间(比如 1 天) import pandas as pd # pandas:表格处理 from quant_data import get_kline # 从数据工具箱拿"拉数据"的函数(真实行情)

1. 基础 · datetime / timedelta

两个核心方法: strptime 字符串 → 时间(P = parse,解析); strftime 时间 → 字符串(F = format,格式化)。
# ========== 1. 基础 ========== print("===== datetime 基础 =====") # strptime:把"字符串"解析成"时间"(P 是 parse = 解析) t = datetime.strptime("2026-08-24 09:30:00", "%Y-%m-%d %H:%M:%S") # 第二个参数是格式:%Y 年 %m 月 %d 日 %H 时 %M 分 %S 秒 print("解析字符串 ->", t) print("加一天 ->", t + timedelta(days=1)) # 时间 + 时间段 = 新时间 print("减 7 小时 ->", t - timedelta(hours=7)) # 时间 - 时间段 = 新时间 # strftime:反过来,"时间"变回"字符串"(F 是 format = 格式化) print("反向格式化 ->", t.strftime("%Y/%m/%d %H:%M")) print("取出年月日 ->", t.year, "年", t.month, "月", t.day, "日") # .year / .month / .day:直接取时间里的年、月、日 print("今天是星期几 ->", t.weekday(), "(0=周一 ... 4=周五, 5=周六, 6=周日)")

2. 与 pandas 联动

核心方法: pd.date_range 生成连续日期; df.loc["起":"止"] 按时间切片。

date_range 生成自然日

# ========== 2. 与 pandas 联动 ========== print("\n===== 与 pandas 联动 =====") # date_range:pandas 生成一串连续的日期 dates = pd.date_range("2026-08-01", "2026-08-24", freq="D") # freq="D":按"天"生成;D = Day(天) print("8 月 1~24 日(自然日):") for d in dates: # 循环:把每个日期拿出来 if d.weekday() < 5: # 条件分支:星期几小于 5(周一~周五) tag = "" # 工作日:不做标注 else: # 周六周日 tag = " <- 周末" # 标注周末 print(f" {d.strftime('%Y-%m-%d')} 星期{d.weekday() + 1}{tag}") # 只保留工作日 workdays = dates[dates.weekday < 5] # 布尔筛选:dates.weekday 是每个日期是星期几,<5 就是工作日 print(f"\n去掉周末后还剩 {len(workdays)} 天 —— 这就是'交易日'的雏形")

真实行情按时间切片

# "按时间切片"(datetime 和 pandas 联动的场景) print("\n===== 真实行情按时间切片 =====") df = get_kline(start_date="20250101") # 拉 2025 年以来的股票日线 df_2025 = df.loc["2025-01-01":"2025-12-31"] # .loc[起点:终点]:按日期切片,两端都算 print(f"2025 年自然日 365 天,行情实际只有 {len(df_2025)} 个交易日") print("原因:行情数据自动跳过周末和节假日 —— 自然日 ≠ 交易日") march = df_2025.loc["2025-03-01":"2025-03-31"] # 再切一个月的试试 print("切出 2025 年 3 月:", len(march), "天")

3. 时间戳换算

Unix 时间戳:从 1970 年 1 月 1 日算起的秒数,很多加密交易所接口用它传时间。
# ========== 3. 时间戳换算 ========== print("\n===== 时间戳 =====") now = datetime.now() # 现在这一刻 print("现在:", now.strftime("%Y-%m-%d %H:%M:%S")) # 格式化打印 epoch = int(now.timestamp()) # .timestamp():把时间变成"从 1970 年 1 月 1 日算起的秒数",叫 Unix 时间戳 print("Unix 时间戳:", epoch, "(很多加密交易所接口用它传时间)") print("从时间戳还原:", datetime.fromtimestamp(epoch)) # fromtimestamp:反过来,把秒数变回时间

核心要点速览

字符串→时间:strptime
时间→字符串:strftime
时间加减:timedelta(days=1)
取年月日:.year / .month / .day
生成日期:pd.date_range
时间切片:df.loc["起":"止"]
自然日:365 天(含周末)
交易日:约 250 天(跳过周末)
Unix 时间戳:.timestamp()
时间戳还原:datetime.fromtimestamp()
金句: strptime 解析字符串, strftime 格式化输出, timedelta 加减时间 —— datetime 把"时间"变成"可以计算的数字"。

运行输出 · python .\datetime_demo.py

PS> python .\datetime_demo.py ===== datetime 基础 ===== 解析字符串 -> 2026-08-24 09:30:00 加一天 -> 2026-08-25 09:30:00 减 7 小时 -> 2026-08-24 02:30:00 反向格式化 -> 2026/08/24 09:30 取出年月日 -> 2026 年 8 月 24 日 今天是星期几 -> 0 (0=周一 ... 4=周五, 5=周六, 6=周日) ===== 与 pandas 联动 ===== 8 月 1~24 日(自然日): 2026-08-01 星期6 <- 周末 2026-08-02 星期7 <- 周末 2026-08-03 星期1 2026-08-04 星期2 2026-08-05 星期3 2026-08-06 星期4 2026-08-07 星期5 2026-08-08 星期6 <- 周末 2026-08-09 星期7 <- 周末 2026-08-10 星期1 2026-08-11 星期2 2026-08-12 星期3 2026-08-13 星期4 2026-08-14 星期5 2026-08-15 星期6 <- 周末 2026-08-16 星期7 <- 周末 2026-08-17 星期1 2026-08-18 星期2 2026-08-19 星期3 2026-08-20 星期4 2026-08-21 星期5 2026-08-22 星期6 <- 周末 2026-08-23 星期7 <- 周末 2026-08-24 星期1 去掉周末后还剩 16 天 —— 这就是'交易日'的雏形 ===== 真实行情按时间切片 ===== [数据源] akshare 不可用(ProxyError),尝试 baostock... login success! logout success! [数据源] baostock 获取成功,共 421 条 2025 年自然日 365 天,行情实际只有 243 个交易日 原因:行情数据自动跳过周末和节假日 —— 自然日 ≠ 交易日 切出 2025 年 3 月: 21 天 ===== 时间戳 ===== 现在: 2026-09-27 22:59:29 Unix 时间戳: 1790521169 (很多加密交易所接口用它传时间) 从时间戳还原: 2026-09-27 22:59:29
关键结论:8 月 1~24 日共 24 个自然日,去掉周末只剩 16 个工作日;
2025 年 365 个自然日,行情实际只有 243 个交易日 —— 自然日 ≠ 交易日。