datetime日期和时间管理


文章目录

  • datetime日期和时间管理
  • 1.概述
  • 2.时间time
  • 2.1.time类基本使用
  • 1.获取时间
  • 2.获取一天中合法时间范围
  • 3.time微妙是整数
  • 3.日期date
  • 3.1.date基本操作
  • 1.查看date获取日历信息
  • 2.时间戳转为日期格式
  • 3.日期合法范围
  • 4.replace创建日期
  • 5.date属性和方法
  • 4.时间计算timedelta
  • 4.1.timedelta基本使用
  • 1.查看timedelta类提供的时间信息
  • 2.转换完整的时间段
  • 4.2.日期算术
  • 1.timedelta计算日期
  • 2.timedelta与整数浮点数算术运算
  • 4.3.日期比较
  • 5.日期和时间datetime
  • 5.1.查看日期和时间
  • 5.2.datetime属性和方法
  • 6.格式化日期
  • 7.时区
  • 7.1.设置时区


1.概述

datetime包含 一些函数和类,用于完成日期和时间的解析,格式化和算术运算.
datetime通过模块将日期和时间做了分类,可以根据需求选择不同的模块,获取日期和时间方便按需使用。下面是模块划分和职责关系
datetime下包含的模块和职业

  • time模块获取时间
  • date模块获取日期
  • timedelta模块计算(日、时、分、秒、微秒、毫秒)日期
  • datetime模块在date和time上封装了操作时间的方法,方便操作日期和时间

2.时间time

时间值用time类表示,time类包含六个参数,分别为hour,minute,second,microsecond,tzinfo,fold,返回格式为hour:minute:second(.microsecond)。常用的参数有:hour、minute、second三个
time实例只包含时间值,不包含与时间关联的日期值。

2.1.time类基本使用

下面通过一些示例介绍使用time类实例对象调用属性获取时间相关操作。

1.获取时间

实例化time对象,并传入时间参数,输出所有时间字段。

t = datetime.time(1, 2, 3, 4)
print(t)
print('hour       :', t.hour)
print('minute     :', t.minute)
print('second     :', t.second)
print('microsecond:', t.microsecond)
print('tzinfo     :', t.tzinfo)

运行结果

1:02:03.000004
hour       : 1
minute     : 2
second     : 3
microsecond: 4
tzinfo     : None
2.获取一天中合法时间范围

min和max类属性可以反应一天中合法的时间范围

import datetime

print('Earliest  :', datetime.time.min)
print('Latest    :', datetime.time.max)
print('Resolution:', datetime.time.resolution)

运行代码,结果展示了一天中合法时间范围最小值和最大值

Earliest  : 00:00:00
Latest    : 23:59:59.999999
Resolution: 0:00:00.000001
3.time微妙是整数

time的微妙被限制为整微妙,如果秒数为浮点数,则会产生一个TypeError异常。

import datetime

for m in [1, 0, 0.1, 0.6]:
    try:
        print('{:02.1f} :'.format(m),
              # 初始化time类,微秒参数为上面列表的值,当值为1和0整数时能够正确显示,如果是后面的0.1浮点数也会报错
              datetime.time(0, 0, 0, microsecond=m))
    except TypeError as err:
        print('ERROR:', err)

运行代码,初始化time实例,当微秒参数为浮点数时产生TypeError错误

1.0 : 00:00:00.000001
0.0 : 00:00:00
ERROR: 'float' object cannot be interpreted as an integer
ERROR: 'float' object cannot be interpreted as an integer

3.日期date

日历用date类表示,使用date实例属性year、month、和day属性可以单独获取相关日期信息。

3.1.date基本操作

1.查看date获取日历信息

下面的例子用不同的格式输出了日期

import datetime

today = datetime.date.today()
print(today)
print('ctime  :', today.ctime())
tt = today.timetuple()
print('tuple  : tm_year  =', tt.tm_year)
print('         tm_mon   =', tt.tm_mon)
print('         tm_mday  =', tt.tm_mday)
print('         tm_hour  =', tt.tm_hour)
print('         tm_min   =', tt.tm_min)
print('         tm_sec   =', tt.tm_sec)
print('         tm_wday  =', tt.tm_wday)
print('         tm_yday  =', tt.tm_yday)
print('         tm_isdst =', tt.tm_isdst)
print('ordinal:', today.toordinal())
print('Year   :', today.year)
print('Mon    :', today.month)
print('Day    :', today.day)

运行结果

2023-02-10
ctime  : Fri Feb 10 00:00:00 2023
tuple  : tm_year  = 2023
         tm_mon   = 2
         tm_mday  = 10
         tm_hour  = 0
         tm_min   = 0
         tm_sec   = 0
         tm_wday  = 4
         tm_yday  = 41
         tm_isdst = -1
ordinal: 738561
Year   : 2023
Mon    : 2
Day    : 10
2.时间戳转为日期格式
import datetime
import time

o = 733114
print('o               :', o)
# 公历日期时间戳转为日期
print('fromordinal(o)  :', datetime.date.fromordinal(o))

t = time.time()
print('t               :', t)
# 根据给定的时间戮,返回一个date对象
print('fromtimestamp(t):', datetime.date.fromtimestamp(t))

运行结果

o               : 733114
fromordinal(o)  : 2008-03-13
t               : 1675995288.686629
fromtimestamp(t): 2023-02-10
3.日期合法范围

查看日期最小值和最大值合法范围

import datetime

print('Earliest  :', datetime.date.min)
print('Latest    :', datetime.date.max)
print('Resolution:', datetime.date.resolution)

运行结果

Earliest  : 0001-01-01
Latest    : 9999-12-31
Resolution: 1 day, 0:00:00
4.replace创建日期
import datetime

d1 = datetime.date(2008, 3, 29)
print('d1:', d1.ctime())

d2 = d1.replace(year=2009)
print('d2:', d2.ctime())

运行结果

d1: Sat Mar 29 00:00:00 2008
d2: Sun Mar 29 00:00:00 2009
5.date属性和方法
import datetime

today = datetime.date(year=2020,month=8,day=31)   #  使用参数创建日期

print('date对象的年份:', today.year)    

print('date对象的月份:', today.month)   

print('date对象的日:', today.day)  

print("date对象的struct_time结构为:",today.timetuple())

print("返回当前公历日期的序数:",today.toordinal())   #  与fromordinal函数作用相反

print("当前日期为星期(其中:周一对应0):{}".format(today.weekday()))

print("当前日期为星期(其中:周一对应1):{}".format(today.isoweekday()))

print("当前日期的年份、第几周、周几(其中返回为元组):",today.isocalendar())

print("以ISO 8601格式‘YYYY-MM-DD’返回date的字符串形式:",today.isoformat())

print("返回一个表示日期的字符串(其格式如:Mon Aug 31 00:00:00 2020):",today.ctime())

print("指定格式为:",today.strftime("%Y/%m/%d"))

print("替换后的日期为:",today.replace(2019,9,29))

运行结果

date对象的年份: 2020
date对象的月份: 8
date对象的日: 31
date对象的struct_time结构为: time.struct_time(tm_year=2020, tm_mon=8, tm_mday=31, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=244, tm_isdst=-1)
返回当前公历日期的序数: 737668
当前日期为星期(其中:周一对应0):0
当前日期为星期(其中:周一对应1):1
当前日期的年份、第几周、周几(其中返回为元组): datetime.IsoCalendarDate(year=2020, week=36, weekday=1)
以ISO 8601格式‘YYYY-MM-DD’返回date的字符串形式: 2020-08-31
返回一个表示日期的字符串(其格式如:Mon Aug 31 00:00:00 2020): Mon Aug 31 00:00:00 2020
指定格式为: 2020/08/31
替换后的日期为: 2019-09-29

4.时间计算timedelta

  • 使用timedelta可以很方便的在日期上做天days,小时hour,分钟minute,秒second,毫秒millisecond,微妙的时间计算microsecond。如果要进行年、月的加减,则需要另外的办法
  • timedelta类的使用,一定要结合date类的对象 或 datetime类的对象使用。也就是说,一定是基于这两个类的对象,进行时间的加、减。
  • 将两个日期相减可以生成一个timedelta,还可以对某个日期增加或减去一个timedelta生成另一个日期。
  • timedelta内部日期按照日、秒、微秒存储

4.1.timedelta基本使用

1.查看timedelta类提供的时间信息

下面的例子演示了timedelta类可以输出的时间信息,包含天days,小时hour,分钟minute,秒second,毫秒millisecond,微妙的时间

import datetime

print('microseconds:', datetime.timedelta(microseconds=1))
print('milliseconds:', datetime.timedelta(milliseconds=1))
print('seconds     :', datetime.timedelta(seconds=1))
print('minutes     :', datetime.timedelta(minutes=1))
print('hours       :', datetime.timedelta(hours=1))
print('days        :', datetime.timedelta(days=1))
print('weeks       :', datetime.timedelta(weeks=1))

运行结果

microseconds: 0:00:00.000001
milliseconds: 0:00:00.001000
seconds     : 0:00:01
minutes     : 0:01:00
hours       : 1:00:00
days        : 1 day, 0:00:00
weeks       : 7 days, 0:00:00
2.转换完整的时间段

使用total_seconds方法可以将给定的时间转换成完整的秒数。

import datetime

for delta in [datetime.timedelta(microseconds=1),
              datetime.timedelta(milliseconds=1),
              datetime.timedelta(seconds=1),
              datetime.timedelta(minutes=1),
              datetime.timedelta(hours=1),
              datetime.timedelta(days=1),
              datetime.timedelta(weeks=1),
              ]:
    print('{:15} = {:8} seconds'.format(
        str(delta), delta.total_seconds())
    )

运行结果等号左边是给定的时间,右边是转换成秒数。

0:00:00.000001  =    1e-06 seconds
0:00:00.001000  =    0.001 seconds
0:00:01         =      1.0 seconds
0:01:00         =     60.0 seconds
1:00:00         =   3600.0 seconds
1 day, 0:00:00  =  86400.0 seconds
7 days, 0:00:00 = 604800.0 seconds

4.2.日期算术

1.timedelta计算日期

日期算术使用标准算术操作符完成,下面的例子展示了使用timedelta对象计算新日期,另外将日期实例相减生成timedelta

import datetime

today = datetime.date.today()
print('Today    :', today)

one_day = datetime.timedelta(days=1)
print('One day  :', one_day)

yesterday = today - one_day
print('Yesterday:', yesterday)

tomorrow = today + one_day
print('Tomorrow :', tomorrow)

print()
print('tomorrow - yesterday:', tomorrow - yesterday)
print('yesterday - tomorrow:', yesterday - tomorrow)

运行结果

Today    : 2023-02-10
One day  : 1 day, 0:00:00
Yesterday: 2023-02-09
Tomorrow : 2023-02-11

tomorrow - yesterday: 2 days, 0:00:00
yesterday - tomorrow: -2 days, 0:00:00
2.timedelta与整数浮点数算术运算

timedelta对象还支持整数、浮点数、和其他timedelta实例运算,下面的例子展示了timedelta算术运算结果。

mport datetime

one_day = datetime.timedelta(days=1)
print('1 day    :', one_day)
print('5 days   :', one_day * 5)
print('1.5 days :', one_day * 1.5)
print('1/4 day  :', one_day / 4)

# assume an hour for lunch
work_day = datetime.timedelta(hours=7)
meeting_length = datetime.timedelta(hours=1)
print('meetings per day :', work_day / meeting_length)

运行结果

1 day    : 1 day, 0:00:00
5 days   : 5 days, 0:00:00
1.5 days : 1 day, 12:00:00
1/4 day  : 6:00:00
meetings per day : 7.0

4.3.日期比较

日期和时间都可以使用标准操作符比较哪个在前哪个在后

import datetime
import time

print('Times:')
t1 = datetime.time(12, 55, 0)
print('  t1:', t1)
t2 = datetime.time(13, 5, 0)
print('  t2:', t2)
print('  t1 < t2:', t1 < t2)

print()
print('Dates:')
d1 = datetime.date.today()
print('  d1:', d1)
d2 = datetime.date.today() + datetime.timedelta(days=1)
print('  d2:', d2)
print('  d1 > d2:', d1 > d2)

运行结果,下面的例子展示了对比时间和日期

Times:
  t1: 12:55:00
  t2: 13:05:00
  t1 < t2: True

Dates:
  d1: 2023-02-10
  d2: 2023-02-11
  d1 > d2: False

5.日期和时间datetime

datetime类由日期和时间构成,提供了更多遍历的方法操作日期和时间。

5.1.查看日期和时间

import datetime

print("现在的时间是:",datetime.datetime.today())

print("返回现在的时间是:",datetime.datetime.now())

print("当前UTC日期和时间是:",datetime.datetime.utcnow())

print("对应时间戳的日期和时间是:",datetime.datetime.fromtimestamp(1234567896))

print("对应UTC时间戳的日期和时间是:",datetime.datetime.utcfromtimestamp(1234567896))

print("公历序列对应的日期和时间是:",datetime.datetime.fromordinal(1))

print("日期和时间的合体为:",datetime.datetime.combine(datetime.date(2020, 8, 31), datetime.time(12, 12, 12)))

运行结果

现在的时间是: 2023-02-10 11:34:12.664558
返回现在的时间是: 2023-02-10 11:34:12.664572
当前UTC日期和时间是: 2023-02-10 03:34:12.664578
对应时间戳的日期和时间是: 2009-02-14 07:31:36
对应UTC时间戳的日期和时间是: 2009-02-13 23:31:36
公历序列对应的日期和时间是: 0001-01-01 00:00:00
日期和时间的合体为: 2020-08-31 12:12:12

5.2.datetime属性和方法

import datetime

now = datetime.datetime(2020,8,31,12,10,10)

print("年为:",now.year)

print("月为:",now.month)

print("日为:",now.day)

print("小时为:",now.hour)

print("分钟为:",now.minute)

print("秒数为:",now.second)

print('当前日期为:', now.date() )

print('当前时间:', now.time() )

print("返回struct_time为",now.timetuple())   #  和date一样

print("返回UTC的struct_time为",now.utctimetuple())

print("返回的公历序列数为:",now.toordinal())   #  和date一样

print("返回标准日期格式为:",now.isoformat())   #  和date一样

print("返回的周几(1表示周一):",now.isoweekday())    #  和date一样

print("返回的周几(0表示周一):",now.weekday())    #  和date一样  

print("now.isocalendar():", now.isocalendar())  #  和date一样

print("now.ctime():",now.ctime())   #  和date一样

print("格式化时间为:",now.strftime('%Y/%m/%d %H:%M:%S'))   #  把日期按照format指定的格式进行格式化

print(datetime.datetime.strptime("2020/12/29 8:8:00",'%Y/%m/%d %H:%M:%S'))

运行结果

年为: 2020
月为: 8
日为: 31
小时为: 12
分钟为: 10
秒数为: 10
当前日期为: 2020-08-31
当前时间: 12:10:10
返回struct_time为 time.struct_time(tm_year=2020, tm_mon=8, tm_mday=31, tm_hour=12, tm_min=10, tm_sec=10, tm_wday=0, tm_yday=244, tm_isdst=-1)
返回UTC的struct_time为 time.struct_time(tm_year=2020, tm_mon=8, tm_mday=31, tm_hour=12, tm_min=10, tm_sec=10, tm_wday=0, tm_yday=244, tm_isdst=0)
返回的公历序列数为: 737668
返回标准日期格式为: 2020-08-31T12:10:10
返回的周几(1表示周一): 1
返回的周几(0表示周一): 0
now.isocalendar(): datetime.IsoCalendarDate(year=2020, week=36, weekday=1)
now.ctime(): Mon Aug 31 12:10:10 2020
格式化时间为: 2020/08/31 12:10:10
2020-12-29 08:08:00

6.格式化日期

datetime对象默认字符串表示使用ISO-8601格式(YYYY-MM-DDTHH:MM:SS.mmmmm),可以使用strftime生成其他格式。
使用datetime.strptime()可以将格式化的字符串转换为datetime实例

import datetime

format = "%a %b %d %H:%M:%S %Y"

today = datetime.datetime.today()
print('ISO     :', today)

s = today.strftime(format)
print('strftime:', s)

d = datetime.datetime.strptime(s, format)
print(d)
print('strptime:', d.strftime(format))

运行结果

ISO     : 2023-02-10 14:49:00.740146
strftime: Fri Feb 10 14:49:00 2023
2023-02-10 14:49:00
strptime: Fri Feb 10 14:49:00 2023

7.时区

在datetime中时区由tzinfo的子类表示。由于tzinfo是一个抽象基类,实际使用时,应该定义一个它的子类,并为一些方法提供实现。
datetime在timezone类中包含了一个原生的实,该类使用了一个UTC 偏移,这个实现不支持一年中不同日期有不同的偏移值,如有些地方采用夏令时,或者有些地方UTC偏移会随时间改变。

7.1.设置时区

1.获取当前的本地日期和UTC日期

from datetime import timezone, timedelta, datetime
utc_time = datetime.utcnow()  # utcnow()获取世界标准时间。
print(f'1、UTC时间为:{utc_time}')

local_time = datetime.now()  # now() 获取本地时间。
print(f'1、本地时间为:{local_time}')

运行结果

1、UTC时间为:2023-02-10 07:15:53.490433
1、本地时间为:2023-02-10 15:15:53.490719
  1. timezone() 设置时区对象,时区偏移值由 timedelta() 提供。
# 通过timezone 设置时区:可以看出定义的时区都是在 UTC时区 基础上进行的 加或减 操作
beijing = timezone(timedelta(hours=8))
print(f'1、北京时区为:{beijing}')

Tokyo = timezone(timedelta(hours=9))
print(f'2、东京时区为:{Tokyo}')

New_York = timezone(timedelta(hours=-4))
print(f'3、纽约时区为:{New_York}')

utc = timezone.utc
print(f'4、世界标准时区为:{utc}')

运行代码,查看设置的时区对象

1、北京时区为:UTC+08:00
2、东京时区为:UTC+09:00
3、纽约时区为:UTC-04:00
4、世界标准时区为:UTC

3.astimezone() 修改时区

# 在 UTC 的时间基础上,用 astimezone() 修改时区
utc_time = datetime.utcnow()  # 获取当前 UTC 时间
print(f'UTC时间为:{utc_time}')
local_time = datetime.now()  # 获取当前本地时间
print(f'本地时间为:{local_time}')

utc = timezone.utc  # 获取 UTC 的时区对象
utc_time = datetime.utcnow().replace(tzinfo=utc)  # 强制转换加上 UTC 时区。此处敲黑板,需要特别注意。
# replace的tzinfo参数为时区对象,所以
# 也可以这样 replace(tzinfo=timezone(timedelta(hours=0))
print(f'1、强制更改后的UTC时间为:{utc_time}')

time_beijing = utc_time.astimezone(beijing)
time_newyork = utc_time.astimezone(New_York)
time_tokyo = utc_time.astimezone(Tokyo)
print('2、更改时区为北京后的时间:', time_beijing)
print('3、获取时区信息:', time_beijing.tzinfo)
print('4、更改时区为东京后的时间:', time_tokyo)
print('5、获取时区信息:', time_tokyo.tzinfo)
print('6、更改时区为纽约后的时间:', time_newyork)
print('7、获取时区信息:', time_newyork.tzinfo)

运行代码,修改时区时间

UTC时间为:2023-02-10 07:15:53.490758
本地时间为:2023-02-10 15:15:53.490767
1、强制更改后的UTC时间为:2023-02-10 07:15:53.490772+00:00
2、更改时区为北京后的时间: 2023-02-10 15:15:53.490772+08:00
3、获取时区信息: UTC+08:00
4、更改时区为东京后的时间: 2023-02-10 16:15:53.490772+09:00
5、获取时区信息: UTC+09:00
6、更改时区为纽约后的时间: 2023-02-10 03:15:53.490772-04:00
7、获取时区信息: UTC-04:00