Python模块之time模块和datetme模块

发布时间 2024-01-01 21:34:26作者: Lea4ning

time模块和datetime模块

【一】概要

  • time 模块和 datetime 模块是 Python 中用于处理时间的两个重要模块。

【二】常见用法

time 模块:

time 模块提供了与时间相关的函数,主要用于获取和处理当前时间、时间戳等。

一些常见的功能包括:

  • time.time(): 返回当前时间的时间戳(自1970年1月1日午夜以来的秒数)。
  • time.sleep(seconds): 使程序休眠指定秒数。
  • time.localtime(): 返回当前时间的结构化时间对象。
  • time.strftime(format, struct_time): 格式化结构化时间对象为字符串。
  • time.strptime(string, format): 将字符串解析为结构化时间对象。

datetime 模块:

datetime 模块提供了处理日期和时间的类,更加灵活和功能强大。

一些常见的功能包括:

  • datetime.datetime.now(): 返回当前日期和时间的 datetime 对象。
  • datetime.timedelta: 表示两个日期或时间之间的差异。
  • datetime.strftime(format): 将 datetime 对象格式化为字符串。
  • datetime.strptime(string, format): 将字符串解析为 datetime 对象。

【三】time模块详解

【1】时间的三种格式

时间戳(Time stamp)

  • 从1970年1月1日(UTC时区)到现在的秒数,他是一组数字

    • UTC时区1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)
    • 1704105829.9809294
    1970年1月1日被选为时间戳的起始点,这个特定的时间点被称为 "Epoch"(时代)或 "Unix Epoch"(Unix时代)。这一选择主要是因为它在计算机科学和工程中提供了一些方便的属性:

    简单计算: 使用起始时间戳来表示时间的秒数,使得时间的计算变得非常简单,特别是涉及到整数秒的计算。时间戳的增加是一个简单的线性增长,方便于计算。

    历史背景: 这个选择与Unix操作系统的发展有关。Unix操作系统的设计者在选择时间起始点时选择了1970年1月1日,从而使得时间戳的实现在Unix系统中更加自然。

    兼容性: 1970年1月1日是一个相对近代的日期,它允许时间戳表示的时间范围既能覆盖过去的历史,又能预测未来的时间。

    这个时间戳的设定成为一种标准,被广泛采用,包括在Unix和类Unix系统中,以及在许多计算机系统和编程语言中。由于其广泛的应用,1970年1月1日被认为是计算机科学中的时间起始点。

结构化时间(struct_time)

  • 不符合我们人类习惯的,是交由计算机查看的,是时间转换时,中间的桥梁
    • time.struct_time(tm_year=2024, tm_mon=1, tm_mday=1, tm_hour=18, tm_min=43, tm_sec=15, tm_wday=0, tm_yday=1, tm_isdst=0)

格式化时间(Format string)

  • 符合我们人类习惯的时间格式
    • 24/01/01 18:46:27

【1.1】UTC时间

UTC(协调世界时,Coordinated Universal Time)是一种国际标准时间,也被称为世界标准时间。它是通过对全球各地的原子钟测量结果进行平均计算得到的时间。UTC与格林尼治标准时间(GMT)几乎相同,通常可以互换使用,但UTC更加精确。

UTC的特点包括:

  1. 基准时间: UTC的基准时间是原子钟的平均时间,这使得它更加精确和稳定。与此相对,GMT的基准是地球自转的平均时间。
  2. 时区无关: UTC不受时区影响,是全球通用的时间标准。它与格林尼治标准时间之间的差异主要是由于地球自转的不规则性而引起的。
  3. 时间表示: UTC使用24小时制表示时间,没有上午或下午的区分,而且没有夏令时的概念。

在计算机科学中,很多系统和应用程序使用UTC作为时间的基准,因为它能够提供一个统一的、不受地理位置和夏令时变化影响的时间标准。在处理时间戳、日历事件、日志记录等方面,使用UTC能够避免时区差异引起的混淆和错误。

【2】三种时间格式详解

【1】Timestamp(时间戳)

import time
print(time.time())

# 查看当前时间戳
# 1704106499.5425801
当你在不同的时间,不同的地点,输出的值是不同的
import time
print(time.time())  # 1704106623.5031831
time.sleep(1)       # 休眠 1 秒
print(time.time())  # 1704106624.511862

【2】struck_time(结构化时间)

  • 分为localtime(本地时间) 和 gmtime(UTC时间)
import time
print(time.localtime()) # 本地时间
# time.struct_time(tm_year=2024, tm_mon=1, tm_mday=1, tm_hour=18, tm_min=59, tm_sec=4, tm_wday=0, tm_yday=1, tm_isdst=0)
print(time.gmtime())  # UTC时间
# time.struct_time(tm_year=2024, tm_mon=1, tm_mday=1, tm_hour=10, tm_min=59, tm_sec=4, tm_wday=0, tm_yday=1, tm_isdst=0)
# 本地时间(北京时间)与UTC时间相差8小时
  • struct_time 元组共有9个元素共九个元素:
    • (年,月,日,时,分,秒,一年中第几周,一年中第几天等)
索引(Index) 属性(Attribute) 值(Values)
0 (年) 比如2023
1 tm_mon(月) 1 - 12
2 tm_mday(日) 1 - 31
3 tm_hour(时) 0 - 23
4 tm_min(分) 0 - 59
5 tm_sec(秒) 0 - 60
6 tm_wday(weekday) 0 - 6(0表示周一)
7 tm_yday(一年中的第几天) 1 - 366
8 tm_isdst(是否是夏令时) 默认为0
  • 9个元素可以通过索引取值得到对应的值
print(time.gmtime()[0])  # 2024
print(time.gmtime()[1])  # 1
print(time.gmtime()[6])  # 0  # 表示周一
  • 同样也可以根据名字取值
print(time.gmtime().tm_year)  # 2024
print(time.gmtime().tm_mon)  # 1
print(time.gmtime().tm_wday)  # 0  # 表示周一

【3】Format string(格式化时间)

  • time.strftime(format,stuck_time)
    • format参数传递的是格式
    • struck_time参数传递的是时间元组struck_time
      • 不填默认的值是localtime
    • time.strftime 函数不支持关键字参数传递,只能按照位置顺序传递参数。
# 可以自定义输出格式

print(time.strftime('%x %X', time.localtime()))
# 01/01/24 19:47:14

print(time.strftime("%y-%m-%d %X",time.localtime()))
# 24-01-01 19:51:11

  • Python中时间日期格式化符号
符号 含义
%y 两位数的年份表示 (00-99)
%Y 四位数的年份表示 (000-9999)
%m 月份 (01-12)
%d 月内中的一天 (0-31)
%H 24小时制小时数 (0-23)
%I 12小时制小时数 (01-12)
%M 分钟数 (00=59)
%S (00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天 (001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数 (00-53)星期天为星期的开始
%w 星期 (0-6),星期天为星期的开始
%W 一年中的星期数 (00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身
# strftime 源码解释

"""
    strftime(format[, tuple]) -> string
    
    根据格式规范将时间元组转换为字符串。
    有关格式代码,请参阅库参考手册。当时间元组未提供时,使用由localtime()返回的当前时间。
    
    常用的格式代码:
    
    %Y  十进制数表示的带世纪的年份。
    %m  十进制数表示的月份 [01,12]。
    %d  十进制数表示的月份中的一天 [01,31]。
    %H  十进制数表示的小时(24小时制) [00,23]。
    %M  十进制数表示的分钟 [00,59]。
    %S  十进制数表示的秒数 [00,61]。
    %z  与UTC的时区偏移。
    %a  区域设置的缩写星期几名称。
    %A  区域设置的完整星期几名称。
    %b  区域设置的缩写月份名称。
    %B  区域设置的完整月份名称。
    %c  区域设置的适当日期和时间表示。
    %I  十进制数表示的小时(12小时制) [01,12]。
    %p  区域设置的AM或PM的等效表示。
    
    可能会有其他代码在您的平台上可用。请参阅C库strftime函数的文档。
"""

【3】时间格式转化

(1) 图示

img

(2)代码展示

time.localtime()time.gmtime()【时间戳>>>结构化时间】
import time
# 时间戳格式
time_timestamp = time.time()

# 时间戳转为结构化时间
print(time.localtime(time_timestamp))
# time.struct_time(tm_year=2024, tm_mon=1, tm_mday=1, tm_hour=19, tm_min=3, tm_sec=42, tm_wday=0, tm_yday=1, tm_isdst=0)

print(time.gmtime(time_timestamp))
# time.struct_time(tm_year=2024, tm_mon=1, tm_mday=1, tm_hour=11, tm_min=3, tm_sec=42, tm_wday=0, tm_yday=1, tm_isdst=0)
time.mktime()【结构化时间>>>时间戳】
import time
# 结构化时间
time_struck_time = time.gmtime()
print(time_struck_time)
# time.struct_time(tm_year=2024, tm_mon=1, tm_mday=1, tm_hour=11, tm_min=35, tm_sec=55, tm_wday=0, tm_yday=1, tm_isdst=0)

# 转为时间戳格式
print(time.mktime(time_struck_time))
# 1704080146.0

# 通过时间戳得到结构化时间与原先的一致
print(time.gmtime(1704080146.0))
# time.struct_time(tm_year=2024, tm_mon=1, tm_mday=1, tm_hour=3, tm_min=35, tm_sec=46, tm_wday=0, tm_yday=1, tm_isdst=0)

time.strftime()【结构化时间>>>格式化时间】
# 结构化时间
time_struck_time = time.localtime()

# 结构化时间转为格式化时间
print(time.strftime("%Y-%m-%d %X", time_struck_time))
# 2024-01-01 19:57:05
time.strptime()【格式化时间>>>结构化时间】
time_str = time.strftime("%x %X")  # 不填默认是localtime
format_str = "%x %X"   # 格式化时间的格式

time_obj = time.strptime(time_str, format_str)
print(time_obj)
# time.struct_time(tm_year=2024, tm_mon=1, tm_mday=1, tm_hour=20, tm_min=6, tm_sec=43, tm_wday=0, tm_yday=1, tm_isdst=-1)
time.ctime()【时间戳>>>格式化时间】
  • 用于将时间戳转换为可读性较好的字符串表示。它接受一个时间戳参数(默认为当前时间戳),并返回一个表示该时间戳的字符串。
  • 相当于time.strftime("%a %b %d %H:%M:%S %Y")
  • 帮我们设定好了格式内容
# strftime
# 需要先将时间戳转为结构化时间(时间元组)
time_timestamp = time.localtime(time.time())
# 再进行格式化
time_striftime = time.strftime("%a %b %d %H:%M:%S %Y", time_timestamp)
print(time_striftime)
# Mon Jan 01 20:15:34 2024



# ctime
# ctime的转化就简单的多
time_ctime = time.ctime(time.time())
print(time_ctime)
# Mon Jan  1 20:15:34 2024
time.asctime()【结构化时间>>>格式化时间】
  • 用于将时间元组转换为可读性较好的字符串表示。它接受一个表示时间的元组参数,返回一个表示该时间的字符串。
  • 相当于time.strftime("%a %b %d %H:%M:%S %Y")
  • 帮我们设定好了格式内容
# strftime
time_striftime = time.strftime("%a %b %d %H:%M:%S %Y", time.localtime())
print(time_striftime)
# Mon Jan 01 20:13:55 2024


# asctime
time_asctime = time.asctime(time.localtime())
print(time_asctime)
# Mon Jan  1 20:13:55 2024

【四】datetime模块详解

【1】自定义日期并格式化
import datetime

res = datetime.date(2024, 1, 1)
# 传入对应的值就可以输出year-month-day
# 当传值错误时将会报错
print(res)  # 2024-01-01

# 报错
res1 = datetime.date(2024, 13, 1)
print(res1)  # ValueError: month must be in 1..12
【2】获取本地详细时间(datetime)

datetime.datetime.today():

  • 返回当前日期和时间的 datetime 对象。
  • 不接受时区信息,返回的对象的时区信息为 None
  • 更符合直觉,通常用于获取当前本地时间。
res = datetime.datetime.today()
print(res)
# 2024-01-01 20:33:55.341260  # 年月日 时分秒.微秒

datetime.datetime.now([tz]):

  • 返回当前日期和时间的 datetime 对象。
  • 可以接受一个时区信息作为可选参数 tz,用于指定返回的时间对象所在的时区,默认为 None,表示本地时区。
  • 具有更灵活的时区控制,可以用于获取特定时区的当前时间。
import datetime

'''获取本地时间'''
current_time_now_local = datetime.datetime.now()
print(current_time_now_local)
# 2024-01-01 20:40:35.367266


'''获取指定时区的时间'''
utc_tz = datetime.timezone.utc
# utc时间
current_time_now_utc = datetime.datetime.now(utc_tz)
print(current_time_now_utc)
# 2024-01-01 12:40:35.367266+00:00
  • 时区转换
    • 在实际应用中,时区处理对于处理跨时区的时间信息非常重要,特别是在处理国际化应用或分布在不同地理位置的系统时。
from datetime import datetime, timezone, timedelta

# 创建一个表示UTC时区的对象
utc_tz = timezone.utc

# 获取当前时间
current_time_utc = datetime.now(utc_tz)
print("UTC时间:", current_time_utc)

# 将时间转换为其他时区
new_tz = timezone(timedelta(hours=8))  # 例如,表示UTC+8的时区
current_time_new_tz = current_time_utc.astimezone(new_tz)
print("转换后的时间:", current_time_new_tz)

# UTC时间: 2024-01-01 12:43:31.613869+00:00
# 转换后的时间: 2024-01-01 20:43:31.613869+08:00
【2.1】通过变量名获取特定的数值
import datetime

# 获取当日的日期
now_time = datetime.datetime.today()
print(now_time)
# 2024-01-01 20:49:05.423782

# 获取年份
print(now_time.year)
# 2024

# 获取月份
print(now_time.month)
# 1

# 获取日
print(now_time.day)
# 1

# 获取星期(weekday星期是0-6) 0表示周一
print(now_time.weekday())
# 0

# 获取星期(weekday星期是1-7) 1表示周一
print(now_time.isoweekday())
# 1

【3】获取本地日期(date)
import datetime

date = datetime.date.today()
print(date)
# 2024-01-01
【4】推迟时间(timedelta)
(1)得到 推迟/提前 的时间
  • 通过现在的时间 + 推迟的时间实现推迟时间
  • 通过现在的时间 - 推迟的时间实现提前时间
# timedelta中可以传递的值
# 不传默认为0,也就是不改变
def __new__(cls, days=0, seconds=0, microseconds=0,milliseconds=0, minutes=0, hours=0, weeks=0):
import datetime

now_time = datetime.datetime.today()
print(now_time)
#  2024-01-01 20:57:14.482330

# 设定推迟的时间
delta_time = datetime.timedelta(days=2, weeks=3, minutes=35, hours=2, seconds=30, microseconds=40, milliseconds=30)

print(now_time + delta_time)
# 2024-01-24 23:32:44.512370
# 日期向后,推迟了3周,2天,2小时,35分钟,30秒,40毫秒,30微秒

print(now_time - delta_time)
# 2023-12-09 18:25:24.329281
# 日期向前,提前了3周,2天,2小时,35分钟,30秒,40毫秒,30微秒
(2)反向得到 推迟/提前 的时间数
import datetime

# 现在的时间
now_time = datetime.datetime.today()
# 推迟的时间数
delta_time = datetime.timedelta(days=2, weeks=3, minutes=35, hours=2, seconds=30, microseconds=40, milliseconds=30)

# 推迟过的时间
delta_today = now_time + delta_time
# 推迟过的时间 - 现在的时间 
delta_time_count = delta_today - now_time
# 得到被推迟的时间
print(delta_time_count)
  • 提前就是+-

【5】小练习:今年还要多少天过生日?

import datetime

# 设置好生日时间
birthday = datetime.date(2020, 12, 27)
# 得到现在的时间
now_date = datetime.date.today()


def count(n):
    delta_time = datetime.timedelta(days=n)
    time = now_date + delta_time
    if time.month == 12 and time.day == 27:
        return n, time
    return count(n + 1)


next_birthday, next_time = count(1)
print(f"你的生日是{birthday},你的下一个生日{next_time},在{next_birthday}天后")
# 你的生日是2020-12-27,你的下一个生日2024-12-27 在361天后
import datetime

mouth = int(input("请输入你的生日月份:").strip())
day = int(input("请输入你的生日日期:").strip())
# 设置好生日时间
birthday = datetime.date(2024, mouth, day)
# 得到现在的时间
now_date = datetime.date.today()


def count(n):
    delta_time = datetime.timedelta(days=n)
    time = now_date + delta_time
    if time.month == mouth and time.day == day:
        return n, time
    return count(n + 1)


next_birthday, next_time = count(1)
print(f"你的下一个生日{next_time},在{next_birthday}天后")