Python:datetime
阅读原文时间:2023年07月09日阅读:1

学习自:datetime — Basic date and time types — Python 3.10.0b2 documentation

datetime模块用于操作date和time。

date和time对象可以分成“感知型”(aware)和“简单型”(naive)两种,分类方法取决于这类对象是否包含时区(timezone)信息。

感知型,代表了一个特定的有意义的时间,比如“北京12:03”、“莫斯科 7:03”

简单型,并不包含任何的定位信息,只是表明用于计算的时间,比如“这段路程花费了2小时14分36秒”

在使用“感知型”时间时,datetime和time对象需要包含时区信息,即在构建这类对象时设置参数tzinfo,即time zone infomation。

注意:只有构建datetime和time对象时才会包含时区信息tzinfo,换言之,只有这两种类型才可以是“感知型”;date一定是“简单型”

  1. datetime.date:日期类,只有year、month、day三个参数;
  2. datetime.time:时间类,参数包含hour、minute、second、microsecond、tzinfo;
  3. datetime.datetime:时间和日期的结合,参数有year、month、day、hour、minute、second、microsecond、tzinfo;
  4. datetime.timedelta:两个date、time、datetime间的时间间隔;
  5. datetime.tzinfo:包含时空信息的抽象类,经常被datetime和time用于时间转化;
  6. datetime.timezone:用UTC时间实现tzinfo抽象类的类;

这些类的继承关系:

timedelta
tzinfo -> timezone
time
date -> datetime

确定一个class是“感知型”还是“简单型”

date对象一定是“简单型”;

time、datetime可能是这两种类型,那么如何判断呢?

“感知型” datetime或time对象x :

  1. x.tzinfo 不是 None;
  2. x.tzinfo.utcoffset(d)不返回None。

其他时候,x都是简单型。

timedelta

timedelta对象代表两个date、time之间的持续时间。

构造方法

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

所有的参数都是可选的,默认值都为0。所有的参数可以是整型或浮点型,正数或负数;

内存中存储的只有days、seconds、microseconds,其他参数都可以被转化:

  • 1ms = 1000 microseconds;
  • 1min = 60 s;
  • 1hour = 3600 s;
  • 1week= 7 days;

days、seconds、microseconds会被规格化存储,这样它们的值都是唯一的,规则是:

  • 0 <= microseconds < 100000;
  • 0 <= seconds < 3600*24;
  • -99999999<= days <= 99999999;

下边这个例子展示了除了days、seconds、microseconds之外的参数如何被转化为上述这三个参数:

delta = timedelta(
days=50,seconds=27,microseconds=10,
milliseconds=29000,minutes=5,hours=8,weeks=2
)

delta
datetime.timedelta(days=64, seconds=29156, microseconds=10)

类属性:

timedelta.resolution:精度(两个不等的timedelta对象之间的可能的最小时间间隔),默认是1μs,即timedelta( microseconds = 1 )

对象属性:用法dt.xxx

days

该timedelta中的天数

seconds

该timedelta中的秒数 0<sec<86399(一天中的秒数)

microseconds

该timedelta中的微秒数

0<μs<999999(一秒的微秒数)

运算

在看以下的运算时,一定要把下边的时间想成这种概念,从A到B需要 t 小时

运算

说明

t1 = t2 + t3

t2、t3时间之和

t1 = t2 - t3

t2、t3时间之差

t1 = t2 * i

t1是t2的整数倍

t1 = t2 * f

t1是t2的f倍,结果如果在精度之外就四舍五入

f = t2 / t3

 

t1 = t2 / f 或 t1 = t2 / i

 

t1 = t2 // i 或 t1 = t2 // t3

t1 = t2 % t3

余数

q,r = divmod ( t1 , t2 )

同时计算商和余数

+t1

前边的符号是正负号,不是加减号

返回一个有着相同值的timedelta对象

-t1

返回 timedelta(-t1.days , -t1.seconds , -t1.microseconds)或者t1 * (-1)

abs( t )

只看t.days,如果>=0就返回+t,否则就返回-t

str ( t )

以格式" D days, H:MM:SS.UUUUUU"返回字符串str,如果t是负数时D就是负数

repr( t )

返回一个String,表示构造该timedelta时,构造函数的写法

除了以上所说的运算,timedelta对象也支持加减date和datetime对象。

此外,也支持两个timedelta间用比较运算符进行比较。

实例方法

timedelta.total_seconds():返回持续时间的总秒数。

例子

关于规格化的例子:

>>> from datetime import timedelta

year = timedelta(days=365)
another_year = timedelta(weeks=40, days=84, hours=23,
… minutes=50, seconds=600)
year == another_year
True
year.total_seconds()
31536000.0

关于timedelta计算的例子:

>>> from datetime import timedelta

year = timedelta(days=365)
ten_years = 10 * year
ten_years
datetime.timedelta(days=3650)
ten_years.days // 365
10
nine_years = ten_years - year
nine_years
datetime.timedelta(days=3285)
three_years = nine_years // 3
three_years, three_years.days // 365
(datetime.timedelta(days=1095), 3)

date

一个date对象代表了一个有着year、month、day的date。

构造函数

datetime.date(year,month,day)

所有参数都需要明确指定,且这些参数必须是整型且需要在指定范围内:

  • MINYEAR <= year <= MAXYEAR
  • 1 <= month <= 12
  • 1<= day <= 该年该月最大天数

类方法:用法date.xxx(…)

today()

返回当前date

fromtimestamp(timestamp)

返回timestamp对应的date

fromisoformat(date_string)

返回格式为'YYYY-MM-DD'的字符串对应的date

frommisocalendar(year,week,day)

返回用year、week、day指定的ISO calendar对应的date;是d.isocalendar()的反函数

类属性:用法date.xxx

resolution

精度,默认timedelta(days=1)

对象属性:用法d.xxx

year

month

day

运算

date2 = date1 + timedelta

date2 = date1 - timedelta

timedelta = date1 - date2

date1 < date2

实例方法:用法d.xxx(…)

replace(year=self.year,month=self.month,day=self.day)

如果不写参数,就返回一个相同的date对象;

否则就用指定参数代替原来的date中的相关值,并返回新的date

timetuple()

返回一个time.struct_time对象,其中hours、minutes、seconds都是0,DST为1

weekday()

返回date指定的日期是一周的哪天:0代表周一,6代表周天

isoweekday()

返回date指定的日期是一周的哪天:1代表周一,7代表周天

isocalendar()

返回一个named tuple(year , week , weekday)

isoformat()

将一个date转化为"YYYY-MM-DD"的String类型

__str__()

这个方法说明该date对象可以用str()字符串化,即通过str(d)将d转化为字符串;

等同于d.isoformat()

ctime()

跟time.ctime()相同,只是除了年月日外的变量都是0

strftime(format)

根据format指定的格式,将date转化为String;hour、minute、second都会转为0

例子

计算到某个日期的天数差:

from datetime import date

today=date.today()
my_birthday=date(today.year,5,24)
if my_birthday < today:#如果生日已经过完
my_birthday=my_birthday.replace(year=today.year+1)
time2birthday=my_birthday-today
print(time2birthday.days)

time

time对象代表了一个独立的时间。如果想要与真实的时间关联(比如“北京 12:00”),需要通过tzinfo对象。

构造函数

time(
hour=0, minute=0, second=0, microsecond=0,
tzinfo=None, *, fold=0
)

所有的参数都是可选的;参数tzinfo要么是None,要么是tzinfo对象;其他参数必须是整数而且必须在指定的范围内:

  • 0 <= hour < 24;
  • 0 <= minute < 60;
  • 0 <= second <60;
  • 0 <= microsecond < 1000000;
  • fold in [ 0 , 1 ];

类属性:用法time.xxx

resolution

精度,timedelta(microseconds=1)

对象属性:用法t.xxx

hour

minute

second

microsecond

微秒

tzinfo

时空信息

需要注意的是,tzinfo标识一个time对象是“感知型”还是“简单型”,没有tzinfo属性(“简单型”)和有tzinfo属性(“感知型”)的两个time无法比较。

如果两个time都有tzinfo属性,表明它们都是“感知型”。如果它们的tzinfo属性相同,那么在比较时会忽略tzinfo而只比较基本时间;如果它们的tzinfo不同,那么它们在比较时会转化为UTC时间再进行比较。

类方法:用法time.xxx(…)

方法

返回值

说明

fromisoformat(str)

time

返回一个格式为"HH[:MM[:SS[.fff[fff]]]] [+HH:MM[:SS[.ffffff]]]"的string对应的time对象,前边每一个中括号[ ]都代表一个可省略项

实例方法:用法t.xxx(…)

方法

返回值

说明

replace(

hour=self.hour,minute=self.minute,second=self.second,

microsecond=self.microsecond,tzinfo=self.tzinfo,*,fold=0

)

time

用参数中指定的time属性代替原time中的指定属性,构成新的time,没指定属性则会直接用原time的属性

isoformat(timespec='auto')

string

以ISO格式返回一个time对应的string;

ISO格式:

microsecond != 0时——HH:MM:SS.ffffff

microsecond == 0 时——HH:MM:SS

参数timespec指定了具体的ISO格式,一般情况下用"auto"就够了,其他的参数可以去官方文档中自行查看

__str__()

 

因为实现了这个方法,所以可以直接用str(t)将time对象t字符串化,功能和isoformat()相同

strftime(format)

string

返回一个format格式指定的time对应的string

utcoffset()

None或timedelta

如果tzinfo是None,就返回None

否则返回self.tzinfo.utcoffset(None),这是一个timedelta对象

dst()

None或timeleta

如果tzinfo是None,就返回None

否则返回self.tzinfo.dst(None),这是一个timedelta对象

tzname()

None或string

如果tzinfo为None,则返回None

否则返回self.tzinfo.tzname(None),这是一个string

此外,格式化字符串时也可以提取time对象的属性之一进行格式化:

'{:%H:%M}'.format(t)
'12:10'

第一个:是格式化字符串的标志,第二个:是时间属性分隔符。

例子

time.fromisoformat( str )

from datetime import time

time.fromisoformat('04:23:01')
datetime.time(4, 23, 1)

time.fromisoformat('04:23:01.000384')
datetime.time(4, 23, 1, 384)

time.fromisoformat('04:23:01+04:00')
datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))

time对象的相关方法

from datetime import time,tzinfo,timedelta
class TZ1(tzinfo): #TZ1是tzinfo的子类
def utcoffset(self,dt):
return timedelta(hours=1)
def dst(self,dt):
return timedelta(0)
def tzname(self,dt):
return '+01:00'
def __repr__(self):
return f'{self.__class__.__name__}()'

t = time(12,10,30,tzinfo=TZ1())
t
datetime.time(12, 10, 30, tzinfo=TZ1())

t.isoformat()
'12:10:30+01:00'

t.dst()
datetime.timedelta(0)

t.tzname()
'+01:00'

t.strftime("%H:%M%S %Z")
'12:10:30 +01:00'

'The {} is {:%H:%M}'.format('time',t)
'The time is 12:10'

datetime

datetime对象同时包含了time和date信息。

构造函数

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

各项的范围:

  • MINYEAR&nbsp;<=&nbsp;year&nbsp;<=&nbsp;MAXYEAR,

  • 1&nbsp;<=&nbsp;month&nbsp;<=&nbsp;12,

  • 1&nbsp;<=&nbsp;day&nbsp;<=&nbsp;number&nbsp;of&nbsp;days&nbsp;in&nbsp;the&nbsp;given&nbsp;month&nbsp;and&nbsp;year,

  • 0&nbsp;<=&nbsp;hour&nbsp;<&nbsp;24,

  • 0&nbsp;<=&nbsp;minute&nbsp;<&nbsp;60,

  • 0&nbsp;<=&nbsp;second&nbsp;<&nbsp;60,

  • 0&nbsp;<=&nbsp;microsecond&nbsp;<&nbsp;1000000,

  • fold&nbsp;in&nbsp;[0,&nbsp;1].

类方法:用法datetime.xxx( … )

类方法

返回值

说明

today()

datetime

返回本地datetime,其中tzinfo=None;

等同于datetime.fromtimestamp( time.time() )

now(tz=None)

datetime

类似today(),只是可以指定tzinfo

utcnow()

datetime

UTC datetime,其中tzinfo=None

fromtimestamp(timestamp,tz=None)

datetime

返回timestamp对应的datetime,可指定tzinfo

utcfromtimestamp(timestamp)

datetime

返回timestamp对应的UTC datetime

combine(date,time,tzinfo=self.tzinfo)

datetime

将一个date和time结合成为一个datetime

fromisoformat(date_string)

datetime

返回string对应的datetime

string格式为:

YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]

*号处可以用任何一个字符

fromisocalendar(year,week,day)

datetime

返回一个ISO Calendar对应的datetime

strptime(date_string,format)

datetime

返回由format指定的date_string对应的datetime

等同于datetime(*(time.strptime(date_string,format)[0:6]))

关于fromisoformat的例子:

>>> from datetime import datetime

datetime.fromisoformat('2011-11-04')
datetime.datetime(2011, 11, 4, 0, 0)

datetime.fromisoformat('2011-11-04T00:05:23')
datetime.datetime(2011, 11, 4, 0, 5, 23)

datetime.fromisoformat('2011-11-04 00:05:23.283')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000)

datetime.fromisoformat('2011-11-04 00:05:23.283+00:00')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc)

>>> datetime.fromisoformat('2011-11-04T00:05:23+04:00')
datetime.datetime(2011, 11, 4, 0, 5, 23,
tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))

类属性

time.resolution:精度,默认timedelta( microsecond=1 )

对象属性:用法t.xxx

year

month

day

hour

minute

second

microsecond

微秒

tzinfo

tzinfo对象

运算

datetime2 = datetime1 + timedelta

datetime2 = datetime1 - timedelta

timedelta = datetime1 - datetime2

datetime1 < datetime2

实例方法:用法t.xxx(…)

方法

返回类型

说明

date()

date

返回组成该datetime的date对象,包括year、month、day属性

time()

time

返回组成该datetime的time对象,包括hour、minute、second、microsecond、fold、tzinfo=None

timetz()

time

返回组成该datetime的time对象,包括上一个函数所说的那些属性,其中tzinfo是datetime的tzinfo

replace(…)

datetime

返回一个用某些属性代替原属性的datetime,没有修改的属性将采用原属性

astimezone(tz=None)

datetime

修改tzinfo属性,date和time同样会修改为对应时区的date与time

utcoffset

None或timedelta

如果tzinfo是None,则返回None

否则返回self.tzinfo.utcoffset(self)

dst()

None或timedelta

如果tzinfo是None,则返回None

否则返回self.tzinfo.dst(self)

tzname()

None或string

如果tzinfo是None,则返回None

否则返回self.tzinfo.tzname(self)

timetuple()

time.struct_time

等价于返回该datetime对应的time.struct_time,即

time.struct_time((

d.year,  d.month,  d.day,

d.hour,  d.minute,  d.second,

d.weekday(),  yday,  dst))

utctimetuple()

time.struct_time

转化为UTC时间下的struct_time;

如果tzinfo=None,则等同于timetuple()函数

timestamp()

timestamp

返回该datetime对应的timestamp

weekday()

int

返回datetime对应一周的哪天(周一到周天 0-6)

isoweekday()

int

返回datetime对应一周的哪天(周一到周天 1-7)

isocalendar()

named tuple

返回有着三元素的named tuple(year , week , weekday)

等同于方法self.date().isocalendar()

isoformat(sep='T',timespec='auto')

string

返回datetime对应的string,format采用ISO format:

当microsecond != 0时,YYYY-MM-DDTHH:MM:SS.ffffff

当microsecond == 0时,YYYY-MM-DDTHH:MM:SS

还有有tzinfo的形式,这里不表,有需要的可以自行去官网查看

参数sep默认是'T',表示date和time间的分隔符

__str__()

 

实现了这个方法,就可以直接用str(d)的方式将datetime字符串化

结果等同于d.isoformat(' ')用' '将date和time分隔开来

ctime()

string

返回datetime对应的string,类似'Wed Dec 4 20:30:40 2002'这种

strftime(format)

string

返回datetime对应的string,可以指定格式

__format__(format)

string

实现了这个功能,就可以直接用一个datetime对一个string进行格式化(见下边的最后一个例子)

例子

from datetime import datetime,date,time

d=date(2005,7,14)
t=time(12,30)
datetime.combine(d,t)
datetime.datetime(2005, 7, 14, 12, 30)

datetime.now()
datetime.datetime(2021, 6, 10, 15, 24, 1, 58813)

dt = datetime.strptime("21/11/06 16:30","%d/%m/%y %H:%M")
dt
datetime.datetime(2006, 11, 21, 16, 30)

tt=dt.timetuple()
tt
time.struct_time(tm_year=2006, tm_mon=11, tm_mday=21, tm_hour=16, tm_min=30, tm_sec=0, tm_wday=1, tm_yday=325, tm_isdst=-1)

ic = dt.isocalendar()
ic
(2006, 47, 2)

dt.strftime("%A, %d. %B %Y %I:%M%p")
'Tuesday, 21. November 2006 04:30PM'

'The {1} is {0:%d},the {2} is {0:%B}, the {3} is {0:%I:%M%p}'.format(dt,'day','month','year')
'The day is 21,the month is November, the year is 04:30PM'

总结

1、timedelta的构造函数:

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

尽管构造时是通过6个参数,但是存储时只能访问3个属性:days、seconds、microseconds,其他的参数都被转化为这3个属性

2、date、time、datetime的构造函数:

datetime.date(year , month , day)
datetime.time(hour=0 , minute=0 , second=0 , microsecond=0)
datetime.datetime(year , month , day , hour=0 , minute=0 , second=0 , microsecond=0)

2.5、三者的对象属性 :以下用d、t、dt代表一个date、time、datetime对象

d.xxx #year month day
t.xxx #hour minute second microsecond tzinfo
dt.xxx #year month day hour minute second microsecond tzinfo

3、三者共有的类方法:xxx.fromisoformat( string ):从一个String转换为Obj

date.fromisoformat(date_string) #YYYY-MM-DD
time.fromisoformat(time_string) #HH:MM:SS.ffffff
datetime.fromisoformat(datetime_string)#YYYY-MM-DD*HH:MM:SS.ffffff(*是任意单个字符)

4、date与datetime共有的类方法:用法xxx.func(…)

  • today():返回当前date/datetime;
  • fromtimestamp(timestamp):返回timestamp对应的date/datetime;
  • 其他(因为不那么重要,这里就不多写了)

5、datetime中的常用类方法:用法datetime.xxx(…)

  • combine(date , time):把一个date和time结合为一个datetime;
  • strptime(string , format):把一个string按照格式format转化为datetime;

4、三者共有的对象方法:x.func(…)——以d、t、dt代表一个date、time、datetime对象

  • replace:用指定属性替代原Obj中的属性

    d.replace(year=self.year , month=self.month , day=self.day)
    t.replace(hour=self.hour , minute=self.minute , second=… , microsecond=…)
    dt.replace( 以上所有参数 )

  • isoformat:将Obj转化为String,格式固定,ISO格式:

    d.isoformat() #'YYYY-MM-DD'
    t.isoformat() #'HH:MM:SS.ffffff'
    dt.isoformat(sep='T') #'YYYY-MM-DDTHH:MM:SS.ffffff',参数是间隔符

  • str(obj):将Obj转化为String,转化方式同isoformat

  • strftime:将Obj转化为String,格式自定:

    d.strftime(format)
    t.strftime(format)
    dt.strftime(format)

5、date、datetime共有对象方法:x.func(…)

  • timetuple:将Obj转化为对应的time.struct_time

    #转化结果为time.struct_time((d.year,d.month,d.day,d.hour,d.minute,d.second,d.weekday(),yday,dst))
    d.timetuple()#hour、minute、second都是0
    dt.timtuple()

  • isocalendar:将Obj转化为一个named tuple( year , week , weekday)

    d.isocalendar()
    dt.isocalendar()

  • ctime:将Obj转化为一个String,类似'Wed Dec 4 20:30:40 2002'

    d.ctime()
    dt.ctime()

6、format表

%y 两位数的年份表示 (00-99)
%Y 四位数的年份表示 (0000-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 本地时间,13:22:44这种形式
%Z 当前时区名称
%% 转义%
%f 微秒

7、str.format( time/date/datetime )

可以直接用time/date/datetime中的属性来对str进行格式化,比如:

'{:%H:%M}'.format(time(12,10,0))
'12:10'

第一个:是格式化字符串的标志,第二个:是字符串中的一般字符,至于各格式化字符的形式,和6中所说的一致。