Python获取当前日期的常用方法与代码示例
在Python开发中,日期和时间处理是不可或缺的基础技能。本文将深入探讨Python中获取当前日期的各种方法,从基础的
datetime
模块到高级的时区处理,为开发者提供全面的日期时间处理指南。
01|datetime模块基础介绍
Python的datetime
模块是处理日期和时间的核心工具,提供了多个重要的类:
datetime.date
:处理日期(年、月、日)datetime.time
:处理时间(时、分、秒、微秒)datetime.datetime
:处理日期和时间datetime.timedelta
:处理时间间隔datetime.tzinfo
:处理时区信息
import datetime
# 查看datetime模块包含的类
print(dir(datetime))
# 输出: ['MAXYEAR', 'MINYEAR', '__builtins__', '__cached__', ... 'date', 'datetime', 'time', 'timedelta', 'tzinfo']
02|获取当前日期的基本方法
2.1 使用datetime.datetime.now()
datetime.now()
是最常用的获取当前日期和时间的方法:
from datetime import datetime
# 获取当前日期和时间
current_datetime = datetime.now()
print(f"当前日期和时间: {current_datetime}")
print(f"类型: {type(current_datetime)}")
# 获取具体的年、月、日、时、分、秒
print(f"年: {current_datetime.year}")
print(f"月: {current_datetime.month}")
print(f"日: {current_datetime.day}")
print(f"时: {current_datetime.hour}")
print(f"分: {current_datetime.minute}")
print(f"秒: {current_datetime.second}")
输出示例:
当前日期和时间: 2025-09-20 22:44:45.123456
类型: <class 'datetime.datetime'>
年: 2025
月: 9
日: 20
时: 22
分: 44
秒: 45
2.2 使用datetime.date.today()
如果只需要日期部分,使用date.today()
更为简洁:
from datetime import date
# 获取当前日期
current_date = date.today()
print(f"当前日期: {current_date}")
print(f"类型: {type(current_date)}")
# 获取具体的年、月、日
print(f"年: {current_date.year}")
print(f"月: {current_date.month}")
print(f"日: {current_date.day}")
# 获取星期几(0=星期一,6=星期日)
print(f"星期几: {current_date.weekday()}")
print(f"星期几(ISO): {current_date.isoweekday()}") # 1=星期一,7=星期日
2.3 使用datetime.utcnow()
获取UTC时间(协调世界时):
from datetime import datetime
# 获取当前UTC时间
utc_datetime = datetime.utcnow()
print(f"UTC时间: {utc_datetime}")
# 比较本地时间和UTC时间
local_datetime = datetime.now()
print(f"本地时间: {local_datetime}")
print(f"时间差: {local_datetime - utc_datetime}")
03|日期格式化详解
3.1 strftime格式化方法
strftime
方法可以将日期时间对象格式化为字符串:
from datetime import datetime
now = datetime.now()
# 常用格式化选项
print(f"默认格式: {now}")
print(f"年-月-日: {now.strftime('%Y-%m-%d')}")
print(f"月/日/年: {now.strftime('%m/%d/%Y')}")
print(f"完整日期时间: {now.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"12小时制: {now.strftime('%Y-%m-%d %I:%M:%S %p')}")
print(f"星期几: {now.strftime('%A')}")
print(f"月份名称: {now.strftime('%B')}")
print(f"简写星期: {now.strftime('%a')}")
print(f"简写月份: {now.strftime('%b')}")
3.2 格式化指令表
指令 | 含义 | 示例 |
---|---|---|
%Y | 四位数年份 | 2025 |
%y | 两位数年份 | 25 |
%m | 月份(01-12) | 09 |
%d | 日期(01-31) | 20 |
%H | 小时(24小时制,00-23) | 22 |
%I | 小时(12小时制,01-12) | 10 |
%M | 分钟(00-59) | 44 |
%S | 秒(00-59) | 45 |
%p | AM/PM | PM |
%A | 完整星期几 | Saturday |
%a | 简写星期几 | Sat |
%B | 完整月份 | September |
%b | 简写月份 | Sep |
3.3 自定义格式化示例
from datetime import datetime
now = datetime.now()
# 创建自定义格式
def custom_date_format(date_obj):
"""自定义日期格式:2025年9月20日 星期六"""
year = date_obj.year
month = date_obj.month
day = date_obj.day
weekday = date_obj.strftime('%A')
return f"{year}年{month}月{day}日 {weekday}"
print(f"自定义格式: {custom_date_format(now)}")
# 时间戳格式
print(f"Unix时间戳: {now.timestamp()}")
print(f"毫秒时间戳: {int(now.timestamp() * 1000)}")
04|时区处理
4.1 基础时区概念
Python 3.2+推荐使用zoneinfo
模块处理时区:
from datetime import datetime
from zoneinfo import ZoneInfo
# 获取当前时间
now = datetime.now()
print(f"本地时间: {now}")
# 获取UTC时间
utc_now = datetime.now(ZoneInfo('UTC'))
print(f"UTC时间: {utc_now}")
# 获取特定时区时间
ny_time = datetime.now(ZoneInfo('America/New_York'))
tokyo_time = datetime.now(ZoneInfo('Asia/Tokyo'))
london_time = datetime.now(ZoneInfo('Europe/London'))
print(f"纽约时间: {ny_time}")
print(f"东京时间: {tokyo_time}")
print(f"伦敦时间: {london_time}")
4.2 时区转换
from datetime import datetime
from zoneinfo import ZoneInfo
# 创建一个UTC时间
utc_time = datetime.now(ZoneInfo('UTC'))
print(f"UTC时间: {utc_time}")
# 转换到不同时区
ny_time = utc_time.astimezone(ZoneInfo('America/New_York'))
tokyo_time = utc_time.astimezone(ZoneInfo('Asia/Tokyo'))
print(f"纽约时间: {ny_time}")
print(f"东京时间: {tokyo_time}")
# 显示时区信息
print(f"UTC时区: {utc_time.tzinfo}")
print(f"纽约时区: {ny_time.tzinfo}")
4.3 处理时区 unaware 对象
from datetime import datetime, timezone
# 无时区信息的时间
naive_time = datetime.now()
print(f"无时区时间: {naive_time}")
print(f"是否有时区: {naive_time.tzinfo is not None}")
# 添加时区信息
aware_time = naive_time.replace(tzinfo=timezone.utc)
print(f"添加UTC时区: {aware_time}")
# 或者使用astimezone添加时区
local_aware = naive_time.astimezone()
print(f"本地时区: {local_aware}")
05|实用代码示例
5.1 日期计算
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
now = datetime.now()
# 加减天数
one_week_later = now + timedelta(days=7)
one_week_ago = now - timedelta(days=7)
print(f"一周后: {one_week_later}")
print(f"一周前: {one_week_ago}")
# 加减月份(使用dateutil)
next_month = now + relativedelta(months=1)
last_month = now - relativedelta(months=1)
print(f"下个月: {next_month}")
print(f"上个月: {last_month}")
# 计算两个日期之间的差值
create_date = datetime(2025, 1, 1)
days_diff = (now - create_date).days
print(f"距离2025年1月1日已过去: {days_diff}天")
5.2 日期验证
from datetime import datetime
def validate_date_string(date_string, format='%Y-%m-%d'):
"""验证日期字符串格式"""
try:
datetime.strptime(date_string, format)
return True
except ValueError:
return False
# 测试日期验证
test_dates = ['2025-09-20', '2025-13-01', '2025-02-29', '2025-02-28']
for date_str in test_dates:
is_valid = validate_date_string(date_str)
print(f"{date_str}: {'有效' if is_valid else '无效'}")
5.3 生成日期范围
from datetime import datetime, timedelta
def generate_date_range(start_date, end_date):
"""生成日期范围"""
current_date = start_date
while current_date <= end_date:
yield current_date
current_date += timedelta(days=1)
# 使用示例
start = datetime(2025, 9, 1)
end = datetime(2025, 9, 5)
print("9月前5天:")
for date in generate_date_range(start, end):
print(date.strftime('%Y-%m-%d'))
5.4 工作日计算
from datetime import datetime, timedelta
def is_weekday(date_obj):
"""判断是否为工作日"""
return date_obj.weekday() < 5 # 0-4 表示周一到周五
def next_workday(date_obj):
"""获取下一个工作日"""
next_day = date_obj + timedelta(days=1)
while not is_weekday(next_day):
next_day += timedelta(days=1)
return next_day
# 测试工作日计算
today = datetime.now()
print(f"今天是工作日: {is_weekday(today)}")
print(f"下一个工作日: {next_workday(today).strftime('%Y-%m-%d')}")
06|常见使用场景
6.1 日志记录
from datetime import datetime
import logging
# 配置日志格式
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# 记录日志
logging.info("应用程序启动")
logging.error("发生错误")
# 自定义日志函数
def log_with_timestamp(message, level='INFO'):
"""带时间戳的日志记录"""
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f"[{timestamp}] {level}: {message}")
log_with_timestamp("用户登录成功")
log_with_timestamp("数据库连接失败", "ERROR")
6.2 文件命名
from datetime import datetime
import os
def generate_filename(prefix='data', extension='txt'):
"""生成带时间戳的文件名"""
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
return f"{prefix}_{timestamp}.{extension}"
def create_daily_folder(base_path='./logs'):
"""创建按日期分类的文件夹"""
today = datetime.now().strftime('%Y-%m-%d')
folder_path = os.path.join(base_path, today)
os.makedirs(folder_path, exist_ok=True)
return folder_path
# 使用示例
filename = generate_filename('report', 'csv')
print(f"生成的文件名: {filename}")
folder = create_daily_folder()
print(f"创建的文件夹: {folder}")
6.3 数据有效期检查
from datetime import datetime, timedelta
class DataCache:
def __init__(self, expiry_hours=24):
self.data = {}
self.expiry_hours = expiry_hours
def set_data(self, key, value):
"""设置数据并记录时间"""
self.data[key] = {
'value': value,
'timestamp': datetime.now()
}
def get_data(self, key):
"""获取数据,检查是否过期"""
if key not in self.data:
return None
data_info = self.data[key]
time_diff = datetime.now() - data_info['timestamp']
if time_diff > timedelta(hours=self.expiry_hours):
del self.data[key] # 删除过期数据
return None
return data_info['value']
def is_expired(self, key):
"""检查数据是否过期"""
if key not in self.data:
return True
time_diff = datetime.now() - self.data[key]['timestamp']
return time_diff > timedelta(hours=self.expiry_hours)
# 使用示例
cache = DataCache(expiry_hours=1)
cache.set_data('user_123', {'name': '张三', 'age': 25})
# 模拟一段时间后检查
import time
time.sleep(2) # 等待2秒
print(f"数据是否过期: {cache.is_expired('user_123')}")
print(f"获取数据: {cache.get_data('user_123')}")
07|最佳实践与性能考虑
7.1 最佳实践
from datetime import datetime, timezone
import pytz
class DateTimeUtils:
"""日期时间工具类"""
@staticmethod
def get_current_utc():
"""获取当前UTC时间"""
return datetime.now(timezone.utc)
@staticmethod
def format_datetime(dt, format_string='%Y-%m-%d %H:%M:%S'):
"""统一格式化日期时间"""
if dt is None:
return None
return dt.strftime(format_string)
@staticmethod
def parse_date_string(date_string, format_string='%Y-%m-%d'):
"""解析日期字符串"""
try:
return datetime.strptime(date_string, format_string)
except ValueError:
return None
@staticmethod
def is_same_day(dt1, dt2):
"""判断是否为同一天"""
return dt1.date() == dt2.date()
# 使用示例
utils = DateTimeUtils()
utc_time = utils.get_current_utc()
print(f"UTC时间: {utils.format_datetime(utc_time)}")
# 解析日期字符串
date_str = "2025-09-20"
parsed_date = utils.parse_date_string(date_str)
print(f"解析结果: {parsed_date}")
7.2 性能优化
import time
from datetime import datetime
def performance_comparison():
"""性能比较测试"""
# 测试datetime.now()的性能
start_time = time.time()
for _ in range(10000):
current_time = datetime.now()
end_time = time.time()
print(f"datetime.now() 10000次耗时: {end_time - start_time:.4f}秒")
# 测试date.today()的性能
start_time = time.time()
for _ in range(10000):
current_date = datetime.today().date()
end_time = time.time()
print(f"datetime.today().date() 10000次耗时: {end_time - start_time:.4f}秒")
# 测试缓存日期的性能
cached_date = datetime.now().date()
start_time = time.time()
for _ in range(10000):
current_date = cached_date
end_time = time.time()
print(f"使用缓存日期 10000次耗时: {end_time - start_time:.4f}秒")
performance_comparison()
7.3 错误处理
from datetime import datetime
import logging
class SafeDateTime:
"""安全的日期时间处理类"""
def __init__(self):
self.logger = logging.getLogger(__name__)
def safe_get_current_date(self):
"""安全获取当前日期"""
try:
return datetime.now().date()
except Exception as e:
self.logger.error(f"获取当前日期失败: {e}")
return None
def safe_format_date(self, date_obj, format_string='%Y-%m-%d'):
"""安全格式化日期"""
if date_obj is None:
return None
try:
return date_obj.strftime(format_string)
except Exception as e:
self.logger.error(f"日期格式化失败: {e}")
return str(date_obj)
def safe_parse_date(self, date_string, format_string='%Y-%m-%d'):
"""安全解析日期字符串"""
if not date_string:
return None
try:
return datetime.strptime(date_string, format_string)
except ValueError as e:
self.logger.warning(f"日期解析失败: {e}, 尝试其他格式")
# 尝试其他常见格式
formats = ['%Y-%m-%d', '%m/%d/%Y', '%d-%m-%Y', '%Y.%m.%d']
for fmt in formats:
try:
return datetime.strptime(date_string, fmt)
except ValueError:
continue
self.logger.error(f"无法解析日期: {date_string}")
return None
# 使用示例
safe_dt = SafeDateTime()
# 测试安全解析
test_dates = ['2025-09-20', '09/20/2025', '2025.09.20', 'invalid-date']
for date_str in test_dates:
result = safe_dt.safe_parse_date(date_str)
print(f"解析 '{date_str}': {result}")
08|总结与建议
核心要点回顾
- 选择合适的方法:根据需求选择
datetime.now()
、date.today()
或utcnow()
- 注意时区处理:在国际化应用中务必正确处理时区
- 格式化一致性:项目中保持日期格式的一致性
- 性能考虑:大批量处理时考虑缓存和批量操作
- 错误处理:始终做好异常处理和输入验证
实用建议
- 使用
zoneinfo
模块处理时区(Python 3.9+) - 考虑使用
dateutil
库处理复杂的日期计算 - 在Web应用中使用ISO 8601格式进行日期传输
- 建立统一的日期时间工具类
- 注意夏令时转换对时间计算的影响
通过掌握这些Python日期时间处理技巧,开发者可以编写出更加健壮和高效的代码,轻松应对各种日期时间相关的业务需求。
思考题:在你的项目中,如何设计一个既支持多时区又具有高性能的日期时间处理系统?考虑缓存策略、时区转换开销以及用户体验的平衡。
(此内容由 AI 辅助生成,仅供参考)