Python时间日期模块使用教程

1. 时间日期处理概述

在日常编程中,时间日期处理是非常常见的需求,比如:

  • 记录日志时间
  • 计算任务执行时长
  • 定时任务调度
  • 数据分析中的时间序列处理

Python提供了多个模块来处理时间日期,主要包括:

  • time - 提供基础时间功能
  • datetime - 高级日期时间处理
  • calendar - 日历相关功能
  • 第三方库如 arrow, pendulum

2. time模块

2.1 time.time()

原型:

time.time() -> float

功能: 返回当前时间的时间戳(从1970年1月1日00:00:00 UTC开始计算的秒数)

参数: 无

返回值: 浮点数,表示时间戳

应用示例: 计算代码执行时间

import time

start_time = time.time()

# 模拟耗时操作
sum_result = 0
for i in range(1000000):
    sum_result += i

end_time = time.time()
execution_time = end_time - start_time
print(f"代码执行耗时: {execution_time:.4f}秒")

注意事项:

  • 时间戳是相对于UTC时间的
  • 浮点数部分表示微秒级精度

2.2 time.sleep()

原型:

time.sleep(seconds: float) -> None

功能: 让程序暂停指定的秒数

参数:

  • seconds: 暂停的秒数,可以是浮点数表示更精确的时间

返回值: 无

应用示例: 定时任务轮询

import time

def check_status():
    print("检查系统状态...")
    # 模拟状态检查
    return True

while True:
    if check_status():
        print("状态正常,5秒后再次检查")
        time.sleep(5)
    else:
        print("状态异常,立即处理")
        break

注意事项:

  • 实际暂停时间可能略长于指定时间
  • 在GUI程序中慎用,可能导致界面无响应

2.3 time.localtime()

原型:

time.localtime([seconds: float]) -> struct_time

功能: 将时间戳转换为本地时间的struct_time对象

参数:

  • seconds: 可选,时间戳,默认为当前时间

返回值: struct_time对象,包含年月日等时间属性

应用示例: 解析时间戳为可读格式

import time

timestamp = time.time()
local_time = time.localtime(timestamp)

print("当前本地时间结构:")
print(f"年: {local_time.tm_year}")
print(f"月: {local_time.tm_mon}")
print(f"日: {local_time.tm_mday}")
print(f"时: {local_time.tm_hour}")
print(f"分: {local_time.tm_min}")
print(f"秒: {local_time.tm_sec}")
print(f"星期几(0-6): {local_time.tm_wday} (0是周一)")
print(f"一年中的第几天: {local_time.tm_yday}")

struct_time属性表:

属性名

描述

取值范围

tm_year

如2023

tm_mon

1-12

tm_mday

1-31

tm_hour

0-23

tm_min

0-59

tm_sec

0-61(60和61是闰秒)

tm_wday

星期几

0-6(0是周一)

tm_yday

一年中的第几天

1-366

tm_isdst

夏令时标志

-1,0,1

注意事项:

  • struct_time是不可变对象
  • tm_isdst为-1表示不确定,0表示不是夏令时,1表示是夏令时

3. datetime模块

datetime模块提供了更高级的日期时间处理功能,包含以下几个主要类:

3.1 date类

原型:

class datetime.date(year, month, day)

功能: 表示日期(年、月、日),不包含时间

常用方法:

  • today(): 返回当前本地日期
  • fromtimestamp(timestamp): 从时间戳创建date对象
  • strftime(format): 格式化日期为字符串

应用示例: 计算两个日期之间的天数

from datetime import date

# 用户注册日期
register_date = date(2023, 1, 15)
# 当前日期
current_date = date.today()

# 计算使用天数
usage_days = (current_date - register_date).days

print(f"用户已使用服务 {usage_days} 天")

3.2 datetime类

原型:

class datetime.datetime(year, month, day, 
                       hour=0, minute=0, second=0, 
                       microsecond=0, tzinfo=None)

功能: 表示日期和时间,包含年、月、日、时、分、秒、微秒和时区信息

常用方法:

  • now(): 返回当前本地日期时间
  • utcnow(): 返回当前UTC日期时间
  • strftime(format): 格式化日期时间为字符串
  • strptime(string, format): 从字符串解析日期时间

应用示例: 日志时间戳格式化

from datetime import datetime

# 获取当前时间
now = datetime.now()

# 格式化为不同的字符串格式
log_format = now.strftime("%Y-%m-%d %H:%M:%S")
file_format = now.strftime("%Y%m%d_%H%M%S")
human_format = now.strftime("%A, %B %d, %Y %I:%M %p")

print(f"日志格式: {log_format}")
print(f"文件命名格式: {file_format}")
print(f"人类可读格式: {human_format}")

# 从字符串解析
date_str = "2023-07-15 14:30:00"
parsed_date = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print(f"解析后的日期时间: {parsed_date}")

常用格式化代码表:

代码

含义

示例

%Y

4位数年份

2023

%y

2位数年份

23

%m

月份(01-12)

07

%d

日(01-31)

15

%H

24小时制小时(00-23)

14

%I

12小时制小时(01-12)

02

%M

分钟(00-59)

30

%S

秒(00-59)

45

%A

星期全名

Monday

%a

星期缩写

Mon

%B

月份全名

July

%b

月份缩写

Jul

%p

AM/PM

PM

%f

微秒(000000-999999)

123456

3.3 timedelta类

原型:

class datetime.timedelta(days=0, seconds=0, 
                        microseconds=0, milliseconds=0, 
                        minutes=0, hours=0, weeks=0)

功能: 表示时间间隔,用于日期时间的加减运算

应用示例: 计算未来日期和倒计时

from datetime import datetime, timedelta

# 当前时间
now = datetime.now()

# 计算30天后的日期
future_date = now + timedelta(days=30)
print(f"30天后的日期是: {future_date.strftime('%Y-%m-%d')}")

# 活动倒计时
event_date = datetime(2023, 12, 31)
time_left = event_date - now
print(f"距离年底还有: {time_left.days}天 {time_left.seconds//3600}小时")

# 计算工作时间段
start_time = datetime(2023, 7, 15, 9, 0)
end_time = datetime(2023, 7, 15, 18, 30)
work_duration = end_time - start_time
print(f"工作时长: {work_duration.seconds//3600}小时{(work_duration.seconds%3600)//60}分钟")

注意事项:

  • 最大时间单位是天,没有月和年,因为它们的长度不固定
  • 支持负数表示过去的时间

4. calendar模块

calendar模块提供与日历相关的功能,如生成日历、判断闰年等。

4.1 calendar.month()

原型:

calendar.month(year, month, w=0, l=0) -> str

功能: 返回某年某月的日历字符串

参数:

  • year: 年份
  • month: 月份
  • w: 每日宽度,默认为0
  • l: 每周行数,默认为0

应用示例: 生成当月日历

import calendar
from datetime import datetime

now = datetime.now()
year = now.year
month = now.month

# 生成当月日历
cal_str = calendar.month(year, month)
print(f"{year}年{month}月日历:")
print(cal_str)

# 设置更宽的格式
wide_cal = calendar.month(year, month, w=4, l=2)
print("加宽格式:")
print(wide_cal)

4.2 calendar.isleap()

原型:

calendar.isleap(year) -> bool

功能: 判断某年是否为闰年

应用示例: 闰年检查器

import calendar

def check_leap_year(year):
    if calendar.isleap(year):
        print(f"{year}年是闰年")
    else:
        print(f"{year}年不是闰年")

# 测试
check_leap_year(2020)  # 闰年
check_leap_year(2023)  # 平年
check_leap_year(2100)  # 不是闰年(能被100整除但不能被400整除)

5. 时区处理

5.1 pytz库

pytz是处理时区的第三方库,提供了完整的时区数据库。

安装:

pip install pytz

应用示例: 时区转换

from datetime import datetime
import pytz

# 获取当前UTC时间
utc_now = datetime.now(pytz.utc)
print(f"UTC时间: {utc_now}")

# 转换为上海时区
shanghai_tz = pytz.timezone('Asia/Shanghai')
shanghai_time = utc_now.astimezone(shanghai_tz)
print(f"上海时间: {shanghai_time}")

# 转换为纽约时区
new_york_tz = pytz.timezone('America/New_York')
new_york_time = utc_now.astimezone(new_york_tz)
print(f"纽约时间: {new_york_time}")

# 列出所有可用时区
print("\n部分可用时区:")
for tz in list(pytz.all_timezones)[:10]:
    print(tz)

注意事项:

  • 时区处理容易出错,建议始终使用UTC时间存储,只在显示时转换
  • pytz的localize方法用于将原始datetime附加时区信息

6. 第三方库推荐

6.1 arrow库

arrow提供了更人性化的API来处理日期时间。

安装:

pip install arrow

应用示例: 人性化时间处理

import arrow

# 获取当前时间
now = arrow.now()
print(f"当前时间: {now}")

# 人性化显示
print(now.humanize())  # 几秒前

# 时区转换
utc_time = now.to('UTC')
print(f"UTC时间: {utc_time}")

# 时间偏移
tomorrow = now.shift(days=1)
print(f"明天这个时候: {tomorrow}")

# 解析字符串
date_str = "2023-07-15 14:30:00"
parsed = arrow.get(date_str, 'YYYY-MM-DD HH:mm:ss')
print(f"解析后的时间: {parsed}")

# 格式化输出
print(parsed.format('MMMM DD, YYYY hh:mm:ss A'))

6.2 pendulum库

pendulum是另一个优秀的日期时间库,提供了更精确和直观的API。

安装:

pip install pendulum

应用示例: 精确时间计算

import pendulum

# 创建时间对象
dt = pendulum.datetime(2023, 7, 15, tz='Asia/Shanghai')
print(f"创建的时间: {dt}")

# 精确计算
period = dt.diff(pendulum.now())
print(f"时间差: {period.in_words()}")

# 时间加减
new_date = dt.add(years=1, months=2, days=3)
print(f"加1年2月3天后: {new_date}")

# 比较时间
if dt > pendulum.yesterday():
    print("这个时间点在昨天之后")

# 时区转换
ny_time = dt.in_timezone('America/New_York')
print(f"纽约时间: {ny_time}")

# 人性化显示
print(pendulum.now().subtract(days=1).diff_for_humans())  # "1 day ago"

7. 综合应用示例

7.1 任务调度器

from datetime import datetime, timedelta
import time

class TaskScheduler:
    def __init__(self):
        self.tasks = []
    
    def add_task(self, name, interval, func, *args, **kwargs):
        """添加定时任务
        
        Args:
            name: 任务名称
            interval: 执行间隔(秒)
            func: 要执行的函数
            *args: 函数参数
            **kwargs: 函数关键字参数
        """
        next_run = datetime.now() + timedelta(seconds=interval)
        self.tasks.append({
            'name': name,
            'interval': interval,
            'func': func,
            'args': args,
            'kwargs': kwargs,
            'next_run': next_run
        })
    
    def run(self):
        """运行调度器"""
        print("任务调度器启动...")
        try:
            while True:
                now = datetime.now()
                
                for task in self.tasks:
                    if now >= task['next_run']:
                        print(f"执行任务: {task['name']} 时间: {now}")
                        try:
                            task['func'](*task['args'], **task['kwargs'])
                        except Exception as e:
                            print(f"任务 {task['name']} 执行出错: {e}")
                        
                        # 更新下次执行时间
                        task['next_run'] = now + timedelta(seconds=task['interval'])
                
                # 每秒检查一次
                time.sleep(1)
                
        except KeyboardInterrupt:
            print("任务调度器停止")

# 示例任务函数
def print_time(msg):
    print(f"当前时间: {datetime.now()}, 消息: {msg}")

def count_numbers(max_num):
    for i in range(1, max_num + 1):
        print(i, end=' ')
    print()

# 使用示例
if __name__ == "__main__":
    scheduler = TaskScheduler()
    scheduler.add_task("打印时间", 5, print_time, "定时消息")
    scheduler.add_task("计数任务", 10, count_numbers, 5)
    
    scheduler.run()

7.2 生日提醒应用

from datetime import datetime, date
import csv
from pathlib import Path

class BirthdayReminder:
    def __init__(self, data_file="birthdays.csv"):
        self.data_file = Path(data_file)
        self.birthdays = []
        self.load_data()
    
    def load_data(self):
        """加载生日数据"""
        if not self.data_file.exists():
            return
            
        with open(self.data_file, mode='r', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            for row in reader:
                self.birthdays.append({
                    'name': row['name'],
                    'birthday': datetime.strptime(row['birthday'], '%Y-%m-%d').date()
                })
    
    def save_data(self):
        """保存生日数据"""
        with open(self.data_file, mode='w', encoding='utf-8', newline='') as f:
            writer = csv.DictWriter(f, fieldnames=['name', 'birthday'])
            writer.writeheader()
            for entry in self.birthdays:
                writer.writerow({
                    'name': entry['name'],
                    'birthday': entry['birthday'].strftime('%Y-%m-%d')
                })
    
    def add_birthday(self, name, birthday):
        """添加生日记录"""
        if isinstance(birthday, str):
            birthday = datetime.strptime(birthday, '%Y-%m-%d').date()
        self.birthdays.append({'name': name, 'birthday': birthday})
        self.save_data()
    
    def get_upcoming_birthdays(self, days=30):
        """获取即将到来的生日"""
        today = date.today()
        upcoming = []
        
        for entry in self.birthdays:
            # 计算今年的生日
            this_year_bday = entry['birthday'].replace(year=today.year)
            
            # 如果今年生日已过,计算明年的
            if this_year_bday < today:
                this_year_bday = this_year_bday.replace(year=today.year + 1)
            
            # 计算距离天数
            delta = (this_year_bday - today).days
            
            if 0 <= delta <= days:
                upcoming.append({
                    'name': entry['name'],
                    'birthday': entry['birthday'],
                    'coming_date': this_year_bday,
                    'days_left': delta
                })
        
        # 按距离天数排序
        upcoming.sort(key=lambda x: x['days_left'])
        return upcoming
    
    def display_upcoming(self, days=30):
        """显示即将到来的生日"""
        upcoming = self.get_upcoming_birthdays(days)
        
        if not upcoming:
            print(f"接下来{days}天内没有生日")
            return
            
        print(f"接下来{days}天内的生日:")
        for entry in upcoming:
            print(f"{entry['name']}: {entry['coming_date'].strftime('%Y-%m-%d')} "
                  f"(还有{entry['days_left']}天, 星期{['一','二','三','四','五','六','日'][entry['coming_date'].weekday()]})")

# 使用示例
if __name__ == "__main__":
    reminder = BirthdayReminder()
    
    # 添加一些示例数据
    if not reminder.birthdays:
        reminder.add_birthday("张三", "1990-05-20")
        reminder.add_birthday("李四", "1985-07-15")
        reminder.add_birthday("王五", "1995-12-31")
    
    # 显示即将到来的生日
    reminder.display_upcoming(60)

8. 注意事项

  1. 时间存储:
  2. 在数据库中始终使用UTC时间存储
  3. 只在显示时转换为本地时间
  4. 时间比较:
  5. 比较时间时确保时区一致
  6. 使用datetime对象比较而非字符串
  7. 性能考虑:
  8. 频繁获取当前时间可能影响性能,必要时可以缓存
  9. 大量时间计算时考虑使用timeit模块测试性能
  10. 错误处理:
  11. 处理无效日期(如2月30日)
  12. 处理时区转换可能出现的异常
  13. 代码可读性:
  14. 使用有意义的变量名如start_time, end_date
  15. 对于复杂的时间计算添加注释

9. 总结

Python提供了丰富的时间日期处理工具,从基础的time模块到高级的datetime模块,再到强大的第三方库如arrowpendulum。选择适合你需求的工具:

  • 简单时间戳和休眠: 使用time模块
  • 常规日期时间处理: 使用datetime模块
  • 复杂时区处理: 使用pytz
  • 更人性化API: 使用arrowpendulum

记住时间日期处理的几个原则:

  1. 明确你的需求(是否需要时间部分,是否需要时区)
  2. 保持一致性(在整个项目中统一时间处理方式)
  3. 考虑性能(对于高频操作)
  4. 注重可读性(使用清晰的变量名和适当的注释)

希望本教程能帮助你掌握Python中的时间日期处理,在实际开发中游刃有余地应对各种时间相关需求!


持续更新Python编程学习日志与技巧,敬请关注!


#编程# #python# #在头条记录我的2025# #分享编程心得#


相关文章

Python日期和时间

说明Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间。时间间隔是以秒为单位的浮点小数。每个时间戳都以自从1970年1月1日午夜(历元)经过了多长时间来表示。pyt...

Python进阶-Day 10 :时间与日期处理

一、学习目标掌握 Python 中 datetime 和 time 模块的基本用法。理解时间戳、日期格式化和时间计算的相关概念。能够编写一个简单的倒计时程序,应用所学知识。二、学习内容与时间安排上午(...

Python格式化:让数据输出更优雅

Python的格式化功能能让数据输出瞬间变得优雅又规范。不管是对齐文本、控制数字精度,还是动态填充内容,它都能轻松搞定。一、基础格式化:从简单拼接开始1. 百分号(%)格式化在Python中,百分号格...

python进阶突破内置模块——日期与时间详解

Python 提供了多个内置模块用于处理日期和时间,涵盖了从基础时间操作到时区管理的各种需求。以下是核心模块及其关键功能的详细说明:1.datetime模块datetime 是处理日期和时间的核心模块...

失业程序员复习python笔记——日期时间

Python有很多处理日期的方式,先看一个简单的例子:from datetime import datetime now = datetime.now() print("当前日期时间:...