时间戳与日期处理完全指南

Python 中各种格式转换、时区处理实战

一、时间戳是什么

做爬虫的时候,时间戳是最常见的参数之一。很多接口要求传入 timestamp 参数,而且格式各不相同:有的要秒级,有的要毫秒级,有的要微秒级。搞不清楚这些区别,请求就会失败。

时间戳(Timestamp)是从某个固定时间点开始计算的秒数或毫秒数。最常用的是 Unix 时间戳,从 1970 年 1 月 1 日 00:00:00 UTC 开始计算。

时间戳的精度
  • 秒级:10 位数字,如 1705315200
  • 毫秒级:13 位数字,如 1705315200000
  • 微秒级:16 位数字,如 1705315200000000

二、基础操作

2.1 获取当前时间戳

import time from datetime import datetime # 秒级时间戳 seconds = int(time.time()) print(f"秒级: {seconds}") # 1705315200 # 毫秒级时间戳 milliseconds = int(time.time() * 1000) print(f"毫秒级: {milliseconds}") # 1705315200000 # 微秒级时间戳 microseconds = int(time.time() * 1000000) print(f"微秒级: {microseconds}") # 1705315200000000

2.2 时间戳转日期

# 秒级转日期 timestamp = 1705315200 dt = datetime.fromtimestamp(timestamp) print(dt) # 2024-01-15 16:00:00 # 毫秒级转日期(先除以 1000) timestamp_ms = 1705315200000 dt = datetime.fromtimestamp(timestamp_ms / 1000) print(dt) # 2024-01-15 16:00:00

2.3 日期转时间戳

# 当前日期转时间戳 dt = datetime.now() timestamp = int(dt.timestamp()) print(f"秒级: {timestamp}") # 指定日期转时间戳 dt = datetime(2024, 1, 15, 16, 0, 0) timestamp = int(dt.timestamp()) print(f"秒级: {timestamp}") # 1705315200

三、格式转换

3.1 字符串转日期

from datetime import datetime # 解析各种格式 dt1 = datetime.strptime('2024-01-15', '%Y-%m-%d') dt2 = datetime.strptime('2024-01-15 16:30:00', '%Y-%m-%d %H:%M:%S') dt3 = datetime.strptime('15/01/2024', '%d/%m/%Y') dt4 = datetime.strptime('Jan 15, 2024', '%b %d, %Y') print(dt1) # 2024-01-15 00:00:00 print(dt2) # 2024-01-15 16:30:00

3.2 日期转字符串

from datetime import datetime dt = datetime.now() # 各种格式 print(dt.strftime('%Y-%m-%d')) # 2024-01-15 print(dt.strftime('%Y-%m-%d %H:%M:%S')) # 2024-01-15 16:30:00 print(dt.strftime('%d/%m/%Y')) # 15/01/2024 print(dt.strftime('%Y年%m月%d日')) # 2024年01月15日

3.3 常用格式符

格式符 含义 示例
%Y 四位年份 2024
%m 月份(01-12) 01
%d 日期(01-31) 15
%H 小时(24小时制) 16
%M 分钟(00-59) 30
%S 秒(00-59) 00
%f 微秒 000000

四、时区处理

4.1 带时区的时间

from datetime import datetime, timezone, timedelta # UTC 时间 utc_now = datetime.now(timezone.utc) print(f"UTC: {utc_now}") # 东八区时间(北京时间) beijing_tz = timezone(timedelta(hours=8)) beijing_now = datetime.now(beijing_tz) print(f"北京: {beijing_now}") # 转换时区 utc_time = datetime.now(timezone.utc) beijing_time = utc_time.astimezone(beijing_tz) print(f"UTC 转北京: {beijing_time}")

4.2 使用 pytz

import pytz from datetime import datetime # 获取时区 beijing = pytz.timezone('Asia/Shanghai') new_york = pytz.timezone('America/New_York') # 创建带时区的时间 dt = datetime(2024, 1, 15, 16, 0, 0) dt_beijing = beijing.localize(dt) print(f"北京: {dt_beijing}") # 转换时区 dt_ny = dt_beijing.astimezone(new_york) print(f"纽约: {dt_ny}")

五、爬虫中的时间处理

5.1 生成接口所需的时间戳

import time def get_timestamp(unit='ms'): """获取时间戳""" if unit == 's': return int(time.time()) elif unit == 'ms': return int(time.time() * 1000) elif unit == 'us': return int(time.time() * 1000000) else: raise ValueError("unit 必须是 's', 'ms' 或 'us'") # 使用 ts_s = get_timestamp('s') ts_ms = get_timestamp('ms') print(f"秒级: {ts_s}") print(f"毫秒级: {ts_ms}")

5.2 解析接口返回的时间

from datetime import datetime def parse_api_time(time_value): """解析 API 返回的各种时间格式""" # 如果是数字(时间戳) if isinstance(time_value, (int, float)): # 判断是秒级还是毫秒级 if time_value > 1e12: # 毫秒级 return datetime.fromtimestamp(time_value / 1000) else: # 秒级 return datetime.fromtimestamp(time_value) # 如果是字符串 elif isinstance(time_value, str): formats = [ '%Y-%m-%d %H:%M:%S', '%Y-%m-%d', '%d/%m/%Y %H:%M:%S', '%Y年%m月%d日', ] for fmt in formats: try: return datetime.strptime(time_value, fmt) except ValueError: continue raise ValueError(f"无法解析时间格式: {time_value}") # 使用 print(parse_api_time(1705315200)) print(parse_api_time(1705315200000)) print(parse_api_time('2024-01-15 16:00:00'))

六、常见问题

6.1 时间戳长度判断

def detect_timestamp_unit(timestamp): """判断时间戳的精度""" length = len(str(int(timestamp))) if length == 10: return '秒级' elif length == 13: return '毫秒级' elif length == 16: return '微秒级' else: return '未知' # 使用 print(detect_timestamp_unit(1705315200)) # 秒级 print(detect_timestamp_unit(1705315200000)) # 毫秒级

6.2 时间加减

from datetime import datetime, timedelta dt = datetime.now() # 加一天 tomorrow = dt + timedelta(days=1) print(f"明天: {tomorrow}") # 减一小时 last_hour = dt - timedelta(hours=1) print(f"一小时前: {last_hour}") # 加 30 分钟 after_30min = dt + timedelta(minutes=30) print(f"30分钟后: {after_30min}")

七、总结

时间处理是爬虫开发中的基础技能。记住这几个核心要点:

操作 方法 注意事项
获取当前时间戳 time.time() 返回浮点数,秒级
时间戳转日期 datetime.fromtimestamp() 毫秒级需要先除以 1000
日期转字符串 dt.strftime() 注意格式符大小写
字符串转日期 datetime.strptime() 格式必须匹配
时区转换 astimezone() 推荐用 pytz

时间处理看起来简单,但细节很多。建议把常用的函数封装成工具类,项目中直接调用,避免重复造轮子。