Python:datetime
学习自: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一定是“简单型”
Class
- datetime.date:日期类,只有year、month、day三个参数;
- datetime.time:时间类,参数包含hour、minute、second、microsecond、tzinfo;
- datetime.datetime:时间和日期的结合,参数有year、month、day、hour、minute、second、microsecond、tzinfo;
- datetime.timedelta:两个date、time、datetime间的时间间隔;
- datetime.tzinfo:包含时空信息的抽象类,经常被datetime和time用于时间转化;
- datetime.timezone:用UTC时间实现tzinfo抽象类的类;
这些类的继承关系:
timedelta tzinfo -> timezone time date -> datetime
确定一个class是“感知型”还是“简单型”
date对象一定是“简单型”;
time、datetime可能是这两种类型,那么如何判断呢?
“感知型” datetime或time对象x :
- x.tzinfo 不是 None;
- 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 <= year <= MAXYEAR
, -
1 <= month <= 12
, -
1 <= day <= number of days in the given month and year
, -
0 <= hour < 24
, -
0 <= minute < 60
, -
0 <= second < 60
, -
0 <= 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 |
如果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中所说的一致。
8、在7中说明了这三种类格式化为String的方式,这里说明String→datetime的方式:datetime.strptime(string,format),这是一个类方法
dt=datetime.datetime.strptime('2020-08-01','%Y-%m-%d')
datetime.datetime(2020, 8, 1, 0, 0)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性