Python 日期和时间


2021年8月23日, Learn eTutorial
1996

在本教程中,您将通过示例掌握在 Python 中处理日期和时间的方法。您将了解用于操作日期和时间的不同模块、如何以特定格式读取和打印时间等。

关于日期和时间的事实

在深入研究日期和时间的工作原理之前,让我们先回顾一下过去,了解计算机是如何计算时间的。事实上,几乎所有计算机都基于 Unix 纪元时间来计算时间,即 1970 年 1 月 1 日 00:00:00 UTC。UTC(协调世界时),通常称为 GMT(格林尼治标准时间),指的是经度 0° 的时间。

与其他编程语言一样,Python 也采用了 Unix 时间的概念,其标准库包含一个名为 time 的常用模块。time 模块有一个名为 time() 的函数,它输出自 Unix 纪元时间以来的秒数。

>>> import time
>>> time.time()
1599329118.616698 

这种 Unix 时间表示法对人类来说极难解析,因此需要另一种方式向用户传达时间。这可以通过将 Unix 时间转换为 UTC,再借助时区偏移将其转换为本地时间来实现。所有时区偏移值的数据库由互联网号码分配局(简称 IANA)维护。

日期和时间标准化

由于人类难以确定以秒为单位的时间,时间格式便以年、月、日、小时等方式计算。我们生活的世界在地理、语言、文化等各个方面都充满了多样性,因此有必要对时间格式进行标准化,以避免所有不必要的复杂性和沟通错误。国际标准化组织提出了 ISO-8601,规定日期格式应按从最重要到最不重要的数据顺序排列。明确地说,标准化的日期格式如下

YYYY-MM-DD HH:MM:SS 

其中 YYYY 表示四位数的年份,MM 和 DD 表示两位数的月份和日期。同样,HH、MM 和 SS 表示两位数的小时、分钟和秒。

这样做的主要好处是避免了日期格式的模糊性。例如,当月份的值是一个有效的数字时,MM-DD-YYYY 或 DD-MM-YYYY 常常会被误解。

Python 日期和时间模块

Python 提供了三个不同的模块来处理日期和时间。它们如下所列:

  1. Calendar 模块
  2. Datetime 模块
  3. Time 模块

让我们从 datetime 模块开始学习,它有助于在 Python 中操作日期和时间。

Datetime 模块中的常量

可以使用 datetime 模块中的两个常量 MINYEARMAXYEAR 导出系统中可表示的最小和最大年份。
MINYEAR 返回日期和日期时间对象中允许的最小年份数,即 1,而 MAXYEAR 给出日期和日期时间对象中允许的最大年份数表示,即 9999

import datetime

#constants in datetime Module
import datetime
print(datetime.MINYEAR)
print(datetime.MAXYEAR) 
1
9999

Datetime 模块中的类

为了操作日期和时间,Python 的 datetime 模块包含以下类,如下表所示。

返回或描述 属性
datetime.date 一个理想化的日期 年、月、日
datetime.time 一个理想化的时间 小时、分钟、秒、微秒和 tzinfo
datetime.datetime 日期和时间的组合 年、月、日、小时、分钟、秒、微秒和 tzinfo
datetime.timedelta 两个实例之间的持续时间 周、天、小时、分钟、秒、微秒、毫秒
datetime.tzinfo 时区信息
datetime.timezone 实现 tzinfo 抽象基类

date、time、datetime 和 timezone 类的对象是不可变的,因此是可哈希的。所以这些对象可以用作字典的键。

Python 日期对象

Python 中的 Date 对象在一个理想化的格里高利历中处理日期。它以标准形式 YYYY-MM-DD 表示日期。

datetime.date(year,month,day) 

这里的参数必须是整数,并且在其规定的范围内,如下所示:

  • 年份必须在 1 到 9999 之间(含)
  • 月份必须在 1 到 12 之间(含)
  • 日期必须在 1 到 31 之间(含),具体取决于年份和月份。

如果任何参数不满足这些范围规范,则会遇到 ValueError

如何获取日期

  1. 使用 today() 方法

    方法 today() 用于获取当前本地日期。在此示例中,我们导入了 datetime 模块,并为 datetime.date 类创建了一个对象 d_ob,该对象调用了 today() 方法。

    import datetime
    
    #Current date
    d_ob = datetime.date.today()
    print(d_ob) 
    
    2020-09-06
    

    结果为您提供当前的本地日期。

  2. 使用 fromtimestamp() 方法

    Unix 时间戳是以特定日期和 1970 年 1 月 1 日之间的秒数表示的时间。例如,1599468233 是一个时间戳。可以借助名为 fromtimestamp() 的方法将时间戳转换为实际日期。

    from datetime import date
    ts = date.fromtimestamp(1599468233)
    print('Date from Timestamp is',ts) 
    
    Date from Timestamp is 2020-09-07 
    
  3. 使用 fromisoformat() 方法

    可以使用 fromisoformat() 方法将以字符串形式给出的日期转换为标准格式。这是一个非常酷的方法,它总是以 YYYY-MM-DD 的格式输出日期。

    from datetime import date
    str = date.fromisoformat('2020-02-14')
    print(str) 
    
    2020-02-14
    
  4. 使用 fromisocalendar() 方法

    当将年、周和日作为参数传递时,fromisocalendar 方法会给出日期。

    from datetime import date
    cal_date = date.fromisocalendar(year=2020,week=20,day=5)
    print(cal_date)
    
    2020-05-15
    

Python datetime 对象

现在假设您想获取当前日期和时间,您可以使用 datetime 模块中的另一个类,即 datetime.datetime。datetime 对象是一个单独的对象,它处理日期对象和时间对象。

 datetime.datetime(year,month,day,hour=0,minute = 0,sec = 0,tzinfo = None)


常用的方法如下所列

  1. 用于获取当前日期和时间的 now() 方法

    Datetime 类调用 now() 方法,如下例所示,以获取当前的本地日期和时间。
    import datetime
    
    #Current date
    dt_ob = datetime.datetime.now()
    print(dt_ob)
    

     

    2020-09-06 15:39:27.272038
    
  2. 用于获取当前日期和时间的 today() 方法

    import datetime
    
    #Current date
    dt_ob = datetime.datetime.today()
    print(dt_ob)
    

     

    2020-09-06 15:39:27.272038
    

    您也可以通过传递关键字参数来实例化 datetime 类,如示例所示:唯一的区别是这里我们没有调用任何特定的方法,而是提供了日期和时间。

    from datetime import datetime
     dt_ob3 = datetime(year = 2020,m = 29,hour = 6,minute = 30,sec
    print(dt_ob3)
    

     

    2020-10-29 06:30:45
    

    也可以单独检索实体,如仅年份、仅月份或仅小时。这可以通过点表示法来完成。

    from datetime import datetime
     dt_ob = datetime(year = 2020,m = 29,hour = 6,minute = 30,sec
    print('Current Year is',dt_ob.year)
    print('Current time is ',dt_ob.hour)
    print('Timestamp of the date is',dt_ob.timestamp())
     
      
    Current Year is  2020
    Current Minute is 6
    Timestamp of the date is 1603938645.0
    
  3. 使用 fromtimestamp() 方法

    from datetime import datetime
    ts = datetime.fromtimestamp(1599468233)
    print('Date from Timestamp is',ts)
    

     

    Date from Timestamp is 2020-09-07 12:43:53
    

Python 中的 timedelta 类是什么

Timedelta 类是 datetime 模块中与上述类一起常用的类,用于查找两个日期或时间的差值,即持续时间。在下面的示例中,我们创建了两个日期对象 d1 和 d2,它们的差值存储在 d3 中。这里,d3 属于 timedelta 类。类似地,两个 datetime 对象的差值会得到一个 timedelta 对象。

from datetime import date,time,datetime

from datetime import date,time,datetime
d1= date(2020,9,2)
d2=date(2019,9,7)
d3 =d1-d2
print('Difference is ',d3)
print("Type is ",type(d3))

t1=datetime(2020,9,2,11,45,30)
t2=datetime(2018,9,7,10,50,40)
print('time Difference is ',(t1-t2)) 

输出


Difference is  361 days, 0:00:00
Type is  <class 'datetime.timedelta'>
time Difference is  726 days, 0:54:50

如何操作两个 timedelta 对象

要操作 timedelta 对象,我们首先需要从 datetime 模块中导入 timedelta 类。

#timedelta objects difference
from datetime import timedelta
td1 = timedelta(weeks=2,days=3)
td2 = timedelta(weeks=1,days=5)
td3 = td1-td2
print(td3)

 

5 days, 0:00:00

负的 timedelta 对象

#timedelta objects difference
from datetime import timedelta td5 = timedelta(sec
td  = timedelta(sec
td7 = td5-td6
print(td7)
print(abs(td7))

-1 day, 23:59:30

以秒为单位的 Timedelta 对象

要以秒为单位获取 timedelta 对象,我们可以使用名为 total_seconds() 的方法,它以秒表示持续时间。

from datetime import timedelta

td1 = timedelta(weeks=2,days=3)
print(td1.total_seconds()) 

 

1468800.0

Python datetime 格式化

我们之前讨论过,不同国家的日期和时间格式不同。例如,在美国,他们依赖的常见日期格式是 MM-DD-YYYY,而在英国,格式是 DD-MM-YYYY。如果月份是一个有效的数字,这就会产生歧义。因此,在 python 中需要一种处理这种歧义的措施,于是就有了两种格式化方法

strftime()

Strftime 方法() 是在所有三个类(date、time、datetime)中定义的格式化方法,用于将给定的日期、时间和日期时间表示为可读的字符串。它只包含一个名为 format 的参数,我们在这里指定所需的日期格式。

下面的可视化图表能让您更清晰地理解这个概念。

strptime

strftime() 方法示例


from datetime import datetime

t = datetime.today()
print(t)

f1 = t.strftime("%m/%d/%Y, %H:%M:%S")
# MM/DD/YYYY H:M:S format
print("Format 1:", f1)

f2 = t.strftime("%d/%m/%Y, %H:%M:%S")
# DD/MM/YYYY H:M:S format
print("Format 2:", f2)

输出


2020-09-27 16:15:36.913768
Format 1: 09/27/2020, 16:15:36
Format 2: 27/09/2020, 16:15:36

strptime()

这是另一种格式化方法,仅由 datetime 对象支持,与 strftime() 方法正好相反。这里,datetime 对象是根据给定的字符串创建的。它包含两个参数:

  1. 日期和时间的字符串('02-14-2020')
  2. 字符串的格式(%d/%m/%Y)

根据以上两个参数,它会产生一个 datetime 对象作为结果。下面的可视化图表阐明了这个概念。

strptime

strptime() 方法示例

from datetime import datetime

Str = "June 5,2020"
print(Str)

dt_ob=datetime.strptime(Str,"%B %d,%Y")
print(dt_ob)

 

输出

June 5,2020
2020-06-05 00:00:00

strptime() 中的 ValueError

当传递给 strptime() 方法的字符串和格式代码不匹配时,Python 会引发 ValueError。例如,


from datetime import datetime

Str = "June 5,2020"

dt_ob=datetime.strptime(Str,"%d %B ,%Y")
print(dt_ob)

 

输出

ValueError: time data 'June 5,2020' does not match format '%d %B ,%Y'

strftime() 和 strptime() 的格式代码。

指令 含义 示例
%a 星期的缩写版本。 Sun, Mon, …, Sat (周日, 周一, ..., 周六)
%A 星期的完整版本。 Sunday, Monday, …, Saturday (星期日, 星期一, ..., 星期六)
%w 星期几,以十进制数表示,其中 0 是星期日,1 是星期一,6 是星期六。 0, 1, …, 6
%d 月份中的第几天,以零填充的十进制数表示。 01, 02, …, 31
%b 月份的缩写版本 Jan, Feb, …, Dec (一月, 二月, ..., 十二月)
%B 月份的完整版本 January, February, …, December (一月, 二月, ..., 十二月)
%m 月份,以零填充的十进制数表示。 01, 02, …, 12
%y 年份的简写版本,不含世纪 00, 01, …, 99
%Y 年份的完整版本,包含世纪 0001, 0002, …, 2013, 2014, …, 9998, 9999
%H 小时,以零填充的十进制数表示 - 24 小时制 00, 01, …, 23
  %I   小时,以零填充的十进制数表示 - 12 小时制   01, 02, …, 12
%p AM 或 PM。 AM, PM (上午, 下午)
%M 分钟,以零填充的十进制数表示。 00, 01, …, 59
%S 秒,以零填充的十进制数表示。 00, 01, …, 59
%f 微秒,以十进制数表示,左侧零填充。 000000, 000001, …, 999999
%z UTC 偏移量,格式为 ±HHMM[SS[.ffffff]] (空), +0000, -0400, +1030, +063415, -030712.345216
%Z 时区名称 (空), UTC, EST, CST
%j 一年中的第几天,以零填充的十进制数表示。 001, 002, …, 366
%U 一年中的周数(星期日为一周的第一天),以零填充的十进制数表示。 00, 01, …, 53
%W 一年中的周数(星期一为一周的第一天),以十进制数表示。 00, 01, …, 53
%c 日期和时间的本地表示。 Tue Aug 16 21:30:00 1988
%x 日期的本地表示。 08/16/88 (无); 08/16/1988 (en_US)
%X 时间的本地表示。 21:30:00
%% 一个字面上的 '%' 字符。 %