time模块
Python 的 time 模块提供了各种与时间相关的函数。这些函数可以用来获取当前时间、操作时间和日期、将时间转换为不同的格式等。
时间表示
在 time 模块中,时间通常有两种表示方式:
- 时间戳(timestamp):表示从1970年1月1日00:00:00(称为Unix纪元或Epoch时间)起至现在的秒数。
- 结构化时间(struct_time):是一个命名元组(namedtuple),包含九个元素,分别表示年、月、日、时、分、秒、星期几、一年中的第几天、夏令时标志。
常用函数
获取当前时间
time.time()
time.time() 函数返回当前时间的时间戳(浮点数),即从1970年1月1日00:00:00(称为Unix纪元或Epoch时间)起至现在的秒数。
import time
# 获取当前时间的时间戳
current_timestamp = time.time()
print("当前时间戳:", current_timestamp)
#输出结果:当前时间戳: 1696416612.345678 # 这里的数字是一个示例,实际运行时会得到不同的时间戳
time.localtime([secs])
将时间戳转换为本地时间的结构化时间。
描述
time.localtime([secs]) 函数将一个时间戳(默认为当前时间)转换为一个本地时间的结构化时间(struct_time)。
参数
- secs(可选):时间戳。如果未提供,则使用当前时间。
案例
import time
# 获取当前时间的时间戳
current_timestamp = time.time()
# 将时间戳转换为本地时间的结构化时间
local_time = time.localtime(current_timestamp)
print("本地时间结构化表示:", local_time)
# 访问结构化时间中的各个元素
print("年:", local_time.tm_year)
print("月:", local_time.tm_mon)
print("日:", local_time.tm_mday)
print("小时:", local_time.tm_hour)
print("分钟:", local_time.tm_min)
print("秒:", local_time.tm_sec)
print("星期几:", local_time.tm_wday) # 0代表星期一,6代表星期日
print("一年中的第几天:", local_time.tm_yday)
print("夏令时标志:", local_time.tm_isdst) # 0代表非夏令时,-1代表信息无效,1代表夏令时
# 输出结果
#本地时间结构化表示: time.struct_time(tm_year=2023, tm_mon=10, tm_mday=4, tm_hour=14, tm_min=30, tm_sec=12, tm_wday=2, tm_yday=277, tm_isdst=0)
#年: 2023
#月: 10
#日: 4
#小时: 14
#分钟: 30
#秒: 12
#星期几: 2 # 代表星期二
#一年中的第几天: 277
#夏令时标志: 0 # 代表非夏令时
time.gmtime([secs])
将时间戳转换为UTC时间的结构化时间。
描述
time.gmtime([secs]) 函数将一个时间戳(默认为当前时间)转换为一个UTC时间的结构化时间(struct_time)。
参数
- secs(可选):时间戳。如果未提供,则使用当前时间。
案例
import time
# 获取当前时间的时间戳
current_timestamp = time.time()
# 将时间戳转换为UTC时间的结构化时间
utc_time = time.gmtime(current_timestamp)
print("UTC时间结构化表示:", utc_time)
# 访问结构化时间中的各个元素(与localtime相同)
print("年:", utc_time.tm_year)
# ...(其他元素类似)
# 输出结果
#UTC时间结构化表示: time.struct_time(tm_year=2023, tm_mon=10, tm_mday=4, tm_hour=6, tm_min=30, tm_sec=12, tm_wday=2, tm_yday=277, tm_isdst=0)
年: 2023
# ...(其他元素的值会根据当前UTC时间而变化)
注意:由于UTC时间与本地时间可能存在时区差异,因此tm_hour等时间元素的值可能与localtime的结果不同。
时间格式化参数
在 strftime 和 strptime 函数中,格式化字符串用于指定时间的格式。以下是一些常用的格式化指令:
符号 |
符号描述 |
举例 |
|
本地(locale)的简化星期名称 |
Mon, Tue, …, Sun |
|
本地完整星期名称 |
Monday, Tuesday, …, Sunday |
|
本地简化的月份名称 |
Jan, Feb, …, Dec |
|
本地完整的月份名称 |
January, February, …, December |
|
本地相应的日期和时间表示 |
例如: Tue Aug 16 01:30:00 1988(注意:实际输出取决于locale) |
|
一个月中的第几天(01-31) |
01, 02, …, 31 |
|
一天中的第几个小时(24小时制,00-23) |
00, 01, …, 23 |
|
一天中的第几个小时(12小时制,01-12) |
01, 02, …, 12 |
|
一年中的第几天(001-366) |
001, 002, …, 366 |
|
月份(01-12) |
01, 02, …, 12 |
|
分钟数(00-59) |
00, 01, …, 59 |
|
本地am或pm的相应符 |
AM, PM |
|
秒(00-61,60和61是为了考虑闰秒的情况) |
00, 01, …, 61(注意:通常秒数为00-59,60和61仅在闰秒时出现) |
|
一年中的第几周(00-53,星期天为一周的开始) |
00, 01, …, 53 |
|
一周中的第几天(0-6,0为星期天) |
0, 1, …, 6 |
|
一年中的第几周(00-53,星期一为一周的开始) |
00, 01, …, 53 |
|
本地相应的日期表示(取决于locale) |
例如: 08/16/88(实际输出取决于locale) |
|
本地相应的时间表示(取决于locale) |
例如: 01:30:00(实际输出取决于locale) |
|
两位数的年份表示(00-99) |
00, 01, …, 99 |
|
四位数的年份表示 |
2023, 1988 |
|
时区的名字(如果不存在为空字符串) |
UTC, CST, … |
|
一个百分号字符 |
% |
时间格式化
time.strftime(format[, t])
将时间元组(struct_time)或默认当前时间转换为一个格式化的时间字符串。
参数:
- format:格式化字符串,指定了时间字符串的格式。
- t(可选):时间元组(struct_time),默认为当前时间。
作用:
根据format指定的格式,将时间元组t转换为一个字符串。
案例
import time
# 获取当前时间的时间元组
current_time = time.localtime()
# 格式化时间字符串
formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", current_time)
# 打印格式化后的时间字符串
print(f"Formatted Time: {formatted_time}") # 例如: Formatted Time: 2023-10-05 14:30:00
# 输出结果:输出的时间字符串将基于当前系统时间,格式如2023-10-05 14:30:00。
time.strptime(string, format)
根据指定的格式解析时间字符串,返回对应的时间元组(struct_time)。
参数:
- string:要解析的时间字符串。
- format:格式化字符串,指定了时间字符串的格式。
作用:
将符合format格式的时间字符串string解析为一个时间元组。
案例
import time
# 时间字符串
time_string = "2023-10-05 14:30:00"
# 解析时间字符串为时间元组
parsed_time = time.strptime(time_string, "%Y-%m-%d %H:%M:%S")
# 打印解析后的时间元组
print(f"Parsed Time Tuple: {parsed_time}") # 例如: Parsed Time Tuple: time.struct_time(tm_year=2023, tm_mon=10, tm_mday=5, tm_hour=14, tm_min=30, tm_sec=0, tm_wday=4, tm_yday=278, tm_isdst=0)
# 也可以将解析后的时间元组转换回格式化的时间字符串以验证
verified_time_string = time.strftime("%Y-%m-%d %H:%M:%S", parsed_time)
print(f"Verified Time String: {verified_time_string}") # 例如: Verified Time String: 2023-10-05 14:30:00
运行结果:
- parsed_time将是一个time.struct_time对象,包含了解析后的时间信息。
- verified_time_string将是一个与原始time_string相同的格式化时间字符串,验证了strptime和strftime的互逆性。
time.struct_time
struct_time是一个命名元组(named tuple),用于表示时间。它通常是通过time.localtime()、time.gmtime()或time.strptime()等函数返回的。
字段
- 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是一个命名元组,但它不支持直接修改其字段。如果需要修改时间,可以创建一个新的struct_time对象或使用其他时间处理函数。
总结
- time.strftime(format[, t]):将时间元组转换为格式化的时间字符串。
- time.strptime(string, format):将格式化的时间字符串解析为时间元组。
- time.struct_time:表示时间的命名元组,包含年、月、日、时、分、秒等信息。
时间运算
时间戳与时间元组
- 时间戳:是一个浮点数,表示从1970年1月1日(称为Unix纪元或Epoch)到当前时间的秒数。它通常用于计算机内部的时间表示和计算。
- 时间元组:是一个命名元组(named tuple),包含九个字段,分别表示年、月、日、时、分、秒、星期几、一年中的第几天以及是否是夏令时。它通常用于人类可读的时间表示。
time() 函数
返回当前时间的时间戳(浮点数)。
import time
# 获取当前时间的时间戳
current_timestamp = time.time()
# 打印当前时间戳
print(f"Current Timestamp: {current_timestamp}") # 例如: Current Timestamp: 1696514230.123456
localtime() 和 gmtime() 函数
将时间戳转换为本地时间或UTC时间的struct_time对象。
参数:
- 可选的时间戳(默认为当前时间)。
作用:
- localtime():将时间戳转换为本地时间(考虑时区)。
- gmtime():将时间戳转换为UTC时间(不考虑时区)。
案例
import time
# 获取当前时间的时间戳
current_timestamp = time.time()
# 将时间戳转换为本地时间
local_time = time.localtime(current_timestamp)
# 将时间戳转换为UTC时间
utc_time = time.gmtime(current_timestamp)
# 打印本地时间和UTC时间
print(f"Local Time: {local_time}") # 例如: Local Time: time.struct_time(tm_year=2023, tm_mon=10, tm_mday=6, tm_hour=10, tm_min=30, tm_sec=12, tm_wday=4, tm_yday=279, tm_isdst=0)
print(f"UTC Time: {utc_time}") # 例如: UTC Time: time.struct_time(tm_year=2023, tm_mon=10, tm_mday=6, tm_hour=2, tm_min=30, tm_sec=12, tm_wday=4, tm_yday=279, tm_isdst=0)
mktime()
将struct_time对象转换为时间戳。
参数:
- struct_time对象。
作用:
将时间元组转换为对应的Unix时间戳。
案例
import time
# 创建一个时间元组
time_tuple = time.struct_time((2023, 10, 6, 10, 30, 12, 4, 279, 0))
# 将时间元组转换为时间戳
timestamp = time.mktime(time_tuple)
# 打印转换后的时间戳
print(f"Timestamp from Time Tuple: {timestamp}") # 例如: Timestamp from Time Tuple: 1696573812.0
时间运算
由于时间戳是一个浮点数,因此可以直接进行加减运算来表示时间的增加或减少。例如,加上3600秒表示增加一小时,减去86400秒表示减少一天。
import time
# 获取当前时间的时间戳
current_timestamp = time.time()
# 增加一小时(3600秒)
future_timestamp = current_timestamp + 3600
# 减少一天(86400秒)
past_timestamp = current_timestamp - 86400
# 将时间戳转换为可读的时间元组
future_time = time.localtime(future_timestamp)
past_time = time.localtime(past_timestamp)
# 打印结果
print(f"Current Time: {time.localtime(current_timestamp)}") # 例如: Current Time: time.struct_time(tm_year=2023, tm_mon=10, tm_mday=6, tm_hour=10, tm_min=50, tm_sec=34, tm_wday=4, tm_yday=279, tm_isdst=0)
print(f"Future Time (1 hour later): {future_time}") # 例如: Future Time (1 hour later): time.struct_time(tm_year=2023, tm_mon=10, tm_mday=6, tm_hour=11, tm_min=50, tm_sec=34, tm_wday=4, tm_yday=279, tm_isdst=0)
print(f"Past Time (1 day earlier): {past_time}") # 例如: Past Time (1 day earlier): time.struct_time(tm_year=2023, tm_mon=10, tm_mday=5, tm_hour=10, tm_min=50, tm_sec=34, tm_wday=3, tm_yday=278, tm_isdst=0)
暂停执行
在Python中,time模块提供了一些用于延迟执行或暂停程序运行的函数。这些函数通常用于在程序执行中插入等待时间,例如在循环之间等待、模拟延迟或在调试期间暂停程序。
time.sleep(seconds)
time.sleep() 是最常用的延迟函数,它会使程序暂停指定的秒数。这个函数接受一个浮点数作为参数,可以是小数,以秒为单位。
import time
print("程序开始")
time.sleep(2) # 暂停2秒
print("2秒后程序继续")
注意事项:
- time.sleep() 会阻塞程序的执行,直到指定的时间过去。
- 在多线程环境中,time.sleep() 会阻塞调用它的线程,而不是整个程序。
time.perf_counter_ns() 和 time.sleep(ns / 1e9) 使用纳秒延迟
虽然 time.sleep() 主要接受秒作为参数,但你可以通过传递纳秒数(通过除以 1e9 转换为秒)来实现更精确的延迟。time.perf_counter_ns() 可以用于获取高精度的时间戳(以纳秒为单位),尽管它本身并不用于延迟,但可以用来测量延迟的准确性。
import time
start_time = time.perf_counter_ns()
# 延迟100毫秒(100,000,000纳秒)
time.sleep(100_000_000 / 1e9)
end_time = time.perf_counter_ns()
elapsed_time = (end_time - start_time) / 1e6 # 转换为毫秒
print(f"延迟了 {elapsed_time:.2f} 毫秒")
注意事项
- 精度和平台差异:time.sleep() 的精度取决于底层操作系统的调度器。在大多数现代操作系统上,它通常能提供毫秒级别的精度,但不一定更精确。
- 避免在需要高性能的循环中使用:在需要高性能的实时应用或紧密循环中,频繁调用 time.sleep() 可能会导致不必要的延迟和性能下降。
- 多线程:在多线程环境中,time.sleep() 会暂停调用它的线程,但不会影响其他线程的执行。
计算代码运行时间
import time
# 获取开始时间的时间戳
start_time = time.time()
# 放置你要测量执行时间的代码块
# 例如,一个简单的循环
for i in range(1000000):
pass
# 获取结束时间的时间戳
end_time = time.time()
# 计算执行时间
execution_time = end_time - start_time
print(f"代码执行时间: {execution_time:.6f} 秒")
详细步骤说明
导入time模块:
import time
这是使用time模块中的函数的前提。
获取开始时间:
start_time = time.time()
time.time()函数返回当前时间的时间戳(即从1970年1月1日00:00:00起至现在的秒数)。这个时间戳作为代码块开始执行的时间点。
放置你要测量执行时间的代码块:
for i in range(1000000):
pass
我们用一个简单的空循环来模拟需要测量执行时间的代码块。你可以替换成任何你想测量的代码。
获取结束时间:
end_time = time.time()
同样使用time.time()函数来获取代码块执行结束后的时间戳。
计算执行时间:
execution_time = end_time - start_time
通过计算结束时间和开始时间的差值,得到代码块的执行时间。
打印执行时间:
print(f"代码执行时间: {execution_time:.6f} 秒")
使用格式化字符串(f-string)来打印执行时间,并保留6位小数。
注意事项
- 精度:time.time()的精度取决于系统的时钟分辨率。对于更高精度的测量,可以考虑使用time.perf_counter(),它提供了更高分辨率的计数器,专门用于测量时间间隔。
- 环境因素:执行时间会受到许多因素的影响,包括系统负载、其他正在运行的进程、硬件性能等。因此,多次运行并取平均值是一个更好的做法。
time.perf_counter()
如果你需要更高精度的测量,可以使用time.perf_counter():
import time
# 获取开始时间
start_time = time.perf_counter()
# 放置你要测量执行时间的代码块
for i in range(1000000):
pass
# 获取结束时间
end_time = time.perf_counter()
# 计算执行时间
execution_time = end_time - start_time
print(f"代码执行时间: {execution_time:.6f} 秒")
time.perf_counter()提供了一个更精确的计数器,适合测量短时间间隔。它通常比time.time()更适合用于性能测量。
转换时区
在Python中,处理时间和时区转换通常涉及两个主要的模块:time 和 pytz。虽然 time 模块提供了基本的日期和时间功能,但处理时区转换时,pytz 模块通常更为强大和方便。
安装 pytz
首先,你需要安装 pytz 模块。如果你还没有安装,可以使用 pip 来安装:
pip install pytz
基本用法
from datetime import datetime
import pytz
# 获取当前UTC时间
utc_now = datetime.utcnow()
# 定义时区
tz_new_york = pytz.timezone('America/New_York')
tz_tokyo = pytz.timezone('Asia/Tokyo')
# 将UTC时间转换为纽约时间
ny_time = utc_now.astimezone(tz_new_york)
# 将UTC时间转换为东京时间
tokyo_time = utc_now.astimezone(tz_tokyo)
print("UTC Time:", utc_now)
print("New York Time:", ny_time)
print("Tokyo Time:", tokyo_time)
将任意时间转换为指定时区
如果你有一个非UTC时间,并且想将其转换为另一个时区,可以先将其转换为UTC时间,然后再转换为目标时区。
from datetime import datetime
import pytz
# 定义一个非UTC时间(例如纽约时间)
ny_time_str = '2023-10-05 14:30:00'
ny_time_fmt = '%Y-%m-%d %H:%M:%S'
ny_time_obj = datetime.strptime(ny_time_str, ny_time_fmt)
# 定义纽约时区
tz_new_york = pytz.timezone('America/New_York')
# 将纽约时间转换为UTC时间
ny_time_aware = tz_new_york.localize(ny_time_obj)
utc_time = ny_time_aware.astimezone(pytz.utc)
# 定义目标时区(例如东京时区)
tz_tokyo = pytz.timezone('Asia/Tokyo')
# 将UTC时间转换为东京时间
tokyo_time = utc_time.astimezone(tz_tokyo)
print("Original New York Time:", ny_time_obj)
print("Converted UTC Time:", utc_time)
print("Converted Tokyo Time:", tokyo_time)
注意事项
- 时区定义:确保使用 pytz.timezone 方法时,提供的时区字符串是有效的。你可以在 pytz 的文档或 IANA 时区数据库中查找有效的时区字符串。
- 时间本地化:当你有一个天真的时间(即没有时区信息的时间)时,你需要先使用 localize 方法将其转换为一个时区感知的时间,然后才能进行时区转换。
- 夏令时:pytz 会自动处理夏令时(DST)的变化,所以你不需要担心夏令时导致的时区偏移问题。
时区的数量和定义
全球时区数量:
- 地球被分为24个时区,每个时区大约覆盖经度15°的区域。但实际上,由于政治、历史等因素,时区的划分并不完全按照经度线来,导致有些地区的时区边界与经度线不完全一致。
- 在pytz中,时区的数量并不是固定的24个,因为pytz包含了更详细的时区划分,例如某些国家或地区可能由于历史、政治原因而使用了特殊的时区规则。
时区的定义:
- 在pytz中,时区是通过字符串来定义的,这些字符串遵循IANA时区数据库的命名规则。
- 常见的时区定义格式是“Area/Location”,其中Area表示地理区域(如亚洲、美洲等),Location表示该区域内的具体地点(如上海、纽约等)。
- 例如,“Asia/Shanghai”表示中国上海所在的时区,“America/New_York”表示美国纽约所在的时区。
使用pytz列出所有时区
可以使用pytz.all_timezones来获取pytz支持的所有时区的列表。这个列表包含了IANA时区数据库中所有时区的字符串表示。
import pytz
# 获取所有时区的列表
all_timezones = pytz.all_timezones
# 打印时区列表
for tz in all_timezones:
print(tz)
注意事项
时区更新:
- 由于政治、历史等因素的变化,时区规则可能会发生变化。因此,你需要确保你使用的pytz库是最新的,以便获取最新的时区信息。
- 可以通过运行pip install --upgrade pytz来更新pytz库。
时区名称:
- 在使用pytz.timezone()函数时,你需要提供正确的时区字符串作为参数。如果你提供的字符串不是有效的时区名称,pytz会抛出一个异常。
- 可以查阅pytz的文档或IANA时区数据库来获取有效的时区字符串列表。
夏令时:
- pytz能够自动处理夏令时的转换。但是,有些时区可能已经停止使用夏令时,或者夏令时的规则发生了变化。因此,在进行时区转换时,你需要确保pytz中的时区信息是最新的。