首页 > temp > 简明python教程 >
-
Python学习笔记:Python的时间操作(time,datetime,timedelta,calendar)
做项目的时候,有一个简单需求,就是取到当前时间5年后的某个时间点,这个要怎么做?
这个不是简单的加5年时间,需要库里有自动识别哪一年是闰年,最后返回准确结果。
看起来简单的需求,但因为对Python类库不熟悉,可能被多个时间对象搞懵!
唯一的办法,只能把python中所有关于时间的模块全部学习一遍,以下记录学习的笔记。
通过学习,得出解决这个问题的方法:
from datetime import datetime from datetime import timedelta from calendar # 方法一、只需要将365*5就是五年的天数,但这里未考虑到闰年的情况 # 如果能判断5年中哪一些是闰年再加上相应的天数就可以得到正确的天数总 # 和,因为篇幅关系就不赘述。 dt = datetime.now() td1 = timedelta(days=365*5) # 这里的365不是固定的,不能这样写 print(dt+td1) # 方法二、如果刚好碰上今年是闰年的2月29日,如果5年后又正好不是闰年,2月份没有29天,那么就会报错,所以还是要判断闰年。 d1 = date.today() print(d1.replace(year=d1.year+5)) # 方法三、可以用到calendar模块中的isleap(year)方法 # .....
以下重点内容标红显示
一、背景知识介绍:
1、时间是人类规定的产物,与长度单位是一个道理,米这个单位也是人类发明的。简单说就是地球自转1圈为1天,地球饶太阳公转1圈为1年,而且根据公转自转度量时间都是不可靠的(因为非匀速无法准确度量),关键是找到匀速的度量工具。
历史上时间计量的方法,比如:
-
- 太阳时:以太阳为基础的相对于原子时不十分精准的时间
- 历书时:描述天体运动的方程式中采用的时间﹐或天体历表中应用的时间,已经被原子时替代,不多做讨论。
- 格林威治时间标准时间(GMT):以本初子午线的平子夜起算的平太阳时,1960年以前曾作为基本时间计量系统被广泛应用,因为地球自转非匀速,所以并不是一个很好的时间度量系统,已经被原子时替代。但是一些原则却被保留了下来,比如将世界分为24个时区。
- 协调世界时(UTC):这是现在主要用的时间系统,为了保证时间的匀速统一,采用原子正常衰变的时间做为基准来度量时间(具体理论不深究),由原子钟提供原子时,然后对世界时进行纠正,在适当的实际加减秒数以达到一致。所以,在不需要精确到秒的情况下,通常将GMT 和UTC 视作等同。
- 中国属于UTC+8区,也就是东八区,需要在UTC时间的基础上加8小时得到北京时间。
- 夏令时:为了节约能源,人为将时钟调快的行为,这是非普遍行为所以在程序中可以不考虑,在中国已经废除了这个制度。如果一定要考虑这个因素可以用到tzinfo对象,因只使用简单时间所以本文未对tzinfo对象做研究。
- ISO8601 :国际标准化组织制定的ISO8601国际标准,是日期和时间的表示方法。比如:2004-05-03T17:30:08+08:00,中间的T代表间隔符,最后的+08:00代表时差。
- 简单型时间:不考虑时区、夏时令等因素,而仅通过运行程序所在地获得时间的返回值。简单型对象更易于理解和使用,代价则是忽略了某些现实性考量。推荐使用!
-
感知型时间:考虑时区、夏时令等因素,将所有情况都考虑进去后得到矫正的时间值,其用来表示一个没有解释空间的固定时间点。python提供一个抽象类接口
tzinfo,通过实现其子类来完善时间,
datetime模块
只提供了一个tzinfo
类,即timezone
类。
2、为什么要知道这些背景知识?
因为Python中出现很多关于时间的术语,比如UTC,如果一个方法返回的是UTC时间,如果不知道以上知识,就无法对返回值有预期。
二、Python 的时间类库概述:
- time模块:包含时间的访问和转换函数,此模块包含一些底层的接口,比如让线程休眠的sleep(),还有提取cpu时间的方法。如果要实现更复杂时间操作,可以用到下面几个对象。
-
timedelta对象
:这是一个代表时间间隔的对象,可以对时间进行计算,还支持与
date
和datetime
对象进行特定的相加和相减运算 - date对象:代表年、月、日的日期对象,也就是说该对象重点操作对象是年月日,忽略时分秒。两个date对象之间,或者date对象和timedalta对象之间,可以做加减运算,可以比大小。
-
time对象:代表某日的(本地)时间,它独立于任何特定日期,并可通过
tzinfo
对象来调整。(tzinfo
对象涉及到时区和夏令时等概念,本文不做讨论) -
datetime对象:对象是包含来自
date
对象和time
对象的所有信息的单一对象。意味着我们大部分情况下只需要用这个对象即可。 -
类继承关系:
object timedelta tzinfo timezone time date datetime
三、time 模块:包含时间的访问和转换功能,time模块不同于datetime中的time对象
1、class time.
struct_time:
为 gmtime()
、 localtime()
和 strptime()的返回值
。它是带有 named tuple 接口的对象:可以通过索引和属性名访问值。 存在以下值:
2、时间戳类型,形式是从 epoch 开始的秒数(浮点型 float),epoch的值可以用time.gmtime(0)查看,一般是1970年1月1日0时开始。
3、字符串类型,形式是字符串,这里包含了时间格式转换成自定义格式字符串的各种函数。
4、函数介绍:
-
-
asctime
([t]):struct_time转字符串,[t]为struct_time类型,不提供此参数则默认用localtime()的值,返回结果如:Sun Jun 2023:21:05 2020 -
ctime
([secs]):将时间戳类型转字符串,[secs]为时间戳秒数,如果不提供则默认以time.time()的值,ctime
(secs)等价于asctime(localtime(secs)),返回结果如:Sun Jun 2023:21:05 2020 -
gmtime
([secs]):将时间戳类型转struct_time类型,注意返回结果是UTC时间,也就是世界标准是时间,不是本地时间,如北京时间是UTC+8小时得到的。[secs]如果不提供则用time.time()的值,反向操作用calendar.timegm()
-
localtime
([secs]):同上,将时间戳类型转struct_time类型,区别在于localtime返回的是本地时间,比如北京时间。
-
mktime
(t):将struct_time类型转成时间戳类型,是localtime()的逆函数,是本地时间,不是UTC时间 -
monotonic
() :返回一个float秒数数值,且不受系统更新时间影响,即如果把系统时间改了那么用time()返回的是修改后的时间戳秒数,因为monotonic
()不是从1970-1-1开始的,这就能用来计算两个monotonic()秒数的间隔。 -
monotonic_ns
() :同上,返回int纳秒 -
sleep
(secs):暂停执行调用线程达到给定的秒数 -
strftime
(format[, t]):struct_time类型转字符串,format字符格式化是必须要指定的(格式如下表),stuct_time不指定的话默认用localtime()的值:
-
< 图2 >
-
-
strptime
(string[, format]):字符串转struct_time类型,format 参数同上,string 和 format 都必须是字符串。 -
time
() :返回以float数表示的从 epoch 开始的秒数的时间值,epoch的值可以用gmtime(0)获得,gmtime()和localtime()默认使用time(),前者返回UTC时间,后者返回本地时间。
-
四、timedelta模块:这是一个代表时间间隔的对象,可以对时间进行计算
1、timedelta对象的标准化:timedelta会将输入的值都归结到天数上,如:timedelta(days=50,seconds=27,microseconds=10,milliseconds=29000,minutes=5,hours=8,weeks=2),将得到datetime.timedelta(days=64, seconds=29156, microseconds=10)的结果
2、支持timedelta对象对象之间的运算:
3、支持timedelta对象之间用关系运算符计算:
>>> from datetime import timedelta >>> delta1 = timedelta(seconds=57) >>> delta2 = timedelta(hours=25, seconds=2) >>> delta2 != delta1 True >>> delta2 == 5 False ########################################## >>> delta2 > delta1 True >>> delta2 > 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '>' not supported between instances of 'datetime.timedelta' and 'int'
4、timedelta
对象还支持与 date
和 datetime
对象进行特定的相加和相减运算:这在下面的date模块中介绍。
5、timedelta.
total_seconds
():返回timedelta对象所表示的时间段以秒为单位的数值。
五、date模块:代表年、月、日的日期对象,也就是说该对象重点操作对象是年月日,忽略时分秒。两个date对象之间,或者date对象和timedalta对象之间,可以做加减运算,可以比对大、小和相等关系。
1、函数介绍:
-
-
today
():返回当前本地日期,比如:date.today(),返回2020-04-14,相当于date.fromtimestamp(time.time())
-
fromtimestamp
(timestamp):返回时间戳格式的日期字符串,timestamp为时间戳,是必填参数,比如:date.fromtimestamp(time.time()),返回:2020-04-14 - fromordinal(days):返回对应于预期格列高利历序号的日期。传入一个从公元1年1月1日开始计算的天数,返回一个具体的年份,现在还没想到应用场景。比如:date.fromordinal(2),返回:0001-01-02。也就是公元1年1月1日。
-
fromisoformat
(date_string):返回一个字符串日期的date对象,只支持YYYY-MM-DD
格式,是date.isoformat()
的逆操作方法,比如:fromisoformat
(“2010-04-20”),返回:datetime.date(2019, 12, 4) - fromisocalendar(year,week,day):返回指定时间的日期,year为年份,week为此年份第几个星期(值范围:平年是1~52,闰年是1~53,闰年是52周加2天所以是53),day为此星期的星期几(值范围:1~7)
-
replace
(year=self.year, month=self.month, day=self.day):替换年月日为一个新日期>>> from datetime import date >>> d = date(2002, 12, 31) >>> d.replace(day=26) datetime.date(2002, 12, 26)
-
timetuple
():返回struct_time类型,即time.localtime()
所返回的类型。但只有year,month,days。另外hours, minutes 和 seconds 值均为 0 - toordinal():与fromordinal(days)是相对应的一对函数,返回日期的对应的从公元1年1月1日开始的天数。比如:date(2020,4,14).toordinal(),返回:737529
- isoweekday():返回星期几,1~7,0代表星期一,以此类推。比如:date(2020,4,14).isoweekday(),返回:1
- isocalendar():返回一个 3 元组 (ISO 年份, ISO 周序号, ISO 周日期),比如:date(2020,4,14).isocalendar(),返回:(2020, 16, 2),代表2020年第16周第二天
-
isoformat():返回格式
YYYY-MM-DD
来表示日期的字符串,这是date.fromisoformat()
的逆操作。比如:date.today().isoformat(),返回:2020-04-14 -
ctime
():返回一个日期字符串,等效于:time.ctime(time.mktime(d.timetuple())),比如:date(2002, 12, 4).ctime(),返回:'Wed Dec 4 00:00:00 2002' - replace(year=self.year, month=self.month, day=self.day):替换年月日返回一个新的date对象。
- strftime(format):返回指定格式的时间字符串。format格式如上面< 图2 >,比如:date.today().strftime("%d/%m/%y"),返回:'11/03/02'
-
2、运算:支持与timedalta对象的运算。
3、date代码示例
-
-
# #计算距离特定事件天数的例子:
>>> import time >>> from datetime import date >>> today = date.today() >>> my_birthday = date(today.year, 6, 24) >>> if my_birthday < today: # 如果生日已经过去,则创建明年的生日 ... my_birthday = my_birthday.replace(year=today.year + 1) >>> my_birthday datetime.date(2008, 6, 24) >>> time_to_birthday = abs(my_birthday - today) >>> time_to_birthday.days 202 #明年生日距离今天的天数
-
>>> from datetime import date >>> # 输出特定格式的日期字符串,注意这里用到的缩写格式字符 >>>print('The {1} is {0:%d}, the {2} is {0:%B}.'.format(d.today(), "day", "month")) 输出:The day is 15, the month is April.
-
六、time对象:代表某日的(本地)时间,它独立于任何特定日期,并可通过 tzinfo
对象来调整。(tzinfo
对象涉及到时区和夏令时等概念,本文不做讨论)
1、函数介绍:
2、time对象计算:time
对象支持 time
与 time
的比较,当 a 时间在 b 之前时,则认为 a 小于 b
>>>from datetime import time >>>t1 = time(1,2,4,333) >>>t2 = time(1,2,4,333) >>>if t1 == t2: >>> print("t1==t2") >>>elif t1 > t2: >>> print("t1>t2") >>>else: >>> print("t1<t2") 结果是:t1==t2
七、datetime对象:对象是包含来自 date
对象和 time
对象的所有信息的单一对象。意味这我们只需要用这个对象即可。
1、函数介绍:
2、datetime对象的计算
[参考资料]
协调世界时:https://baike.baidu.com/item/%E5%8D%8F%E8%B0%83%E4%B8%96%E7%95%8C%E6%97%B6/787659?fr=aladdin
Python的time模块:https://docs.python.org/zh-cn/3/library/time.html
Python的datetime模块:https://docs.python.org/zh-cn/3/library/datetime.html
ISO 8601时间格式:https://baike.baidu.com/item/ISO%208601/3910715?fr=aladdin
-
-
构造方法
datetime.
time
(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0):这个对象只有时分秒和微秒,没有年月日,tzinfo代表时区调整对象,fold代表夏时令。类方法time.
fromisoformat
(time_string):返回对应于time.isoformat()
所提供的某种 time_string 格式的time,比如:
- >>> 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.
replace
(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0) :修改参数将返回一个代表新值的time对象。 -
对象方法
time.
isoformat
(timespec='auto'):返回时间的字符串,可以通过timespec选择相应的部分返回,比如:timespec='hours'
: 以两个数码的HH
格式。 -
对象方法
time.
strftime
(format):指定格式并且返回时间字符串,格式化字符参考<图3>。
-
-
构造器datetime
(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0):year, month, day是必须的参数。tzinfo代表时区,fold代表夏令时,这两者可以忽略,返回一个datetime对象 。比如:print(datetime(2001,1,1)) -
类方法datetime.
today
():返回当地时间的datetime对象,等价于datetime.fromtimestamp(time.time()) 和now()方法,但此方法不涉及时区,而now()可以设置时区。
-
类方法datetime.
now
(tz=None):返回当地时间的datetime对象,tz为时区未指定跟today()一样,此方法比time.time()返回更高精度的时间(微妙级别100万精度),此函数可以替代
。比如:today()
和utcnow()
datetime.
now
() -
类方法datetime.
utcnow
():返回表示当前UTC时间的datetime对象,UTC时间和当地时间的区别在于时区,可以参考前文背景分析。 -
类方法datetime.
fromtimestamp
(timestamp, tz=None):通过时间戳返回datetime对象。 -
类方法datetime.
utcfromtimestamp
(timestamp):通过时间戳返回UTC时间的datetime对象。 -
类方法datetime.
fromordinal
(ordinal):返回对应于预期格列高利历序号的datetime对象,ordinal代表从公元1年1月1日开始的int型天数,但时分秒都为0。比如:print(datetime.fromordinal(2)),返回:0001-01-02 00:00:00
-
类方法datetime.
combine
(date, time, tzinfo=self.tzinfo):返回date对象和time对象的datetime对象,比如:>>>d1 = datetime.today() >>>print(d1.date()) 2020-04-15 >>>print(d1.time()) 14:08:41.000856 >>>d2 = datetime.today() >>>print(d2.date()) 2020-04-15 >>>print(d2.time()) 14:08:41.000856 >>>if d2 == datetime.combine(d1.date(), d1.time(), d1.tzinfo): >>> print("这两个datetime对象相等") 结果:这两个datetime对象相等
-
类方法datetime.
fromisoformat
(date_string):从字符串转成datetime对象,字符串参数可以由date.isoformat()
和datetime.isoformat()
来提供,比如:栏目列表最新更新- nodejs爬虫
- Python正则表达式完全指南
- 爬取豆瓣Top250图书数据
- shp 地图文件批量添加字段
- 爬虫小试牛刀(爬取学校通知公告)
- 【python基础】函数-初识函数
- 【python基础】函数-返回值
- HTTP请求:requests模块基础使用必知必会
- Python初学者友好丨详解参数传递类型
- 如何有效管理爬虫流量?
- 2个场景实例讲解GaussDB(DWS)基表统计信息估
- 常用的 SQL Server 关键字及其含义
- 动手分析SQL Server中的事务中使用的锁
- openGauss内核分析:SQL by pass & 经典执行
- 一招教你如何高效批量导入与更新数据
- 天天写SQL,这些神奇的特性你知道吗?
- openGauss内核分析:执行计划生成
- [IM002]Navicat ODBC驱动器管理器 未发现数据
- 初入Sql Server 之 存储过程的简单使用
- SQL Server -- 解决存储过程传入参数作为s
- 关于JS定时器的整理
- JS中使用Promise.all控制所有的异步请求都完
- js中字符串的方法
- import-local执行流程与node模块路径解析流程
- 检测数据类型的四种方法
- js中数组的方法,32种方法
- 前端操作方法
- 数据类型
- window.localStorage.setItem 和 localStorage.setIte
- 如何完美解决前端数字计算精度丢失与数
-
-