Python:datetime

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

datetime模块用于操作datetime

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

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

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

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

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

Class

  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:包含时空信息的抽象类,经常被datetimetime用于时间转化
  6. datetime.timezone:用UTC时间实现tzinfo抽象类的类;

这些类的继承关系:

timedelta
tzinfo        -> timezone
time
date         -> datetime

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

date对象一定是“简单型”

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

“感知型” datetimetime对象

  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需要 小时

运算 说明
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对象也支持加减datedatetime对象。

此外,也支持两个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对象代表了一个有着yearmonthday的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 <= year <= MAXYEAR,

  • <= month <= 12,

  • <= day <= number of days in the given month and year,

  • <= hour 24,

  • <= minute 60,

  • <= second 60,

  • <= microsecond 1000000,

  • fold in [0, 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

如果tzinfoNone,则返回None

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

dst() None或timedelta

如果tzinfoNone,则返回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',表示datetime间的分隔符

__str__()  

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

结果等同于d.isoformat(' ')' 'datetime分隔开来

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):把一个datetime结合为一个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中所说的一致。

8、在7中说明了这三种类格式化为String的方式,这里说明Stringdatetime的方式:datetime.strptime(string,format),这是一个类方法

dt=datetime.datetime.strptime('2020-08-01','%Y-%m-%d')
datetime.datetime(2020, 8, 1, 0, 0)

 

posted @   ShineLe  阅读(309)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示