python 有很多种方式处理日期和时间,常见的时间处理的模块是datetime、time、calendar。能融汇贯通的了解和使用这三个模块,才能轻而易举地用python处理时间。本文以此为目的,通过讲述各个时间模块的概述、函数及相关知识细节、以及相应的示例来讲透它们的使用方式。
这三个模块中,datetime(日期时间)模块主要是用来表示日期的,就是我们常说的年月日时分秒,calendar(日历)模块主要是用来表示年月日,是星期几之类的信息,time(时间)模块主要侧重点在时分秒,粗略从功能来看,我们可以认为三者是一个互补的关系,各自专注一块。方便用户依据不同的使用目的选用趁手的模块。
文章着重点在于梳理出三个模块的设计脉络,便于大家记忆里面的api。在需要的时候能够去查找相应的方法。由于文章篇幅较长,故将三个模块和示例的讲解拆分成几篇前后关联的文章,本文中重点讲解datetime模块。
一、概述
time模块是比较基础的一个模块,可满足对时间类型数据的基本处理;而 datetime模块可以看做是对time模块的一个高级封装,功能更加强大。time模块解决了时间的获取和表示,datetime模块则进一步解决了快速获取并操作时间中的年月日时分秒信息的能力。
datetime模块是这三个时间模块中使用的相对较为频繁,datetime有六个类,比较常用的有datetime、date、time、timedelta这四个,类date和类time可以看作是类datetime的子类别,虽然是分开的,但实际上这三个类的使用方法(函数)基本上是一样的,所以学精通类datetime的属性和方法,基本上可以无障碍的使用另两个类了。
需要特别注意的是,datetime模块中的类time和time模块间的区别,不要混淆它们的用法,它们其中一个只是datetime模块中的一个类别,需要用from datetime import time来进行引用,而另一个是一个独立的模块,只需要用import time。如果同时使用这两个'time',那请直接导入datetime模块和time模块,更细致的导入datetime模块中的类time会混淆两者的使用。
timedelta是datetime模块中的一个非常有用的模块,时间类型数据的计算可以通过timedelta方便快捷的实行,可以通过timedelta设置一个时间间隔,然后与指定时间进行计算,既可以获取某个时间范围内的目标,也可以计算时间间隔前后的日期时间。
有一点需要提前说明一下,time类和datetime类都有一个属性,它的值是一个tzinfo对象,里面包含了该time或者datetime的时区信息,一般称这个time或者datetime对象是aware的,它能够准确换算成自epoch开始的秒数。
如果该属性设置为None,那么,这时的time对象或者datetime对象就没有时区信息,具体它表示的是local time还是utc time,需要我们自己在程序中去决定。
这里我们所说的local time是指我们所在时区的时间, utc time指的就是国际标准时间,也就是格林尼治时间。在本文中不会涉及讲解市区和夏令时的相关操作,一切默认为localtime。
datetime对象就是date对象和time对象的组合。
# 导入datetime模块三个核心的类 from datetime import datetime # class one:datetime 日期时间 from datetime import date # class two:date 日期 from datetime import time # class three:time 时间
直接将时间的值逐个以参数的形式来创建
## 直接创建 datetime(2020,1,1,19,30,0,520) date(2020,1,1) time(19,30,0,520)
执行结果:
datetime.datetime(2020, 1, 1, 19, 30, 0, 520) datetime.date(2020, 1, 1) datetime.time(19, 30, 0, 520)
获取当前日期用today,因为日期的最小计算单位是天,当前日期就是今天;date对象只有today一种获取当前时间的方法,datetime对象却有today和now两种,结果是一致的,time对象没有获取当前时间的方法,不过可以通过datetime对象来获取。
datetime.now() # 获取当前日期时间 datetime.today() # 获取当前日期时间 date.today() # 获取当前日期
执行结果:
datetime.datetime(2019, 12, 31, 14, 26, 21, 655429) datetime.datetime(2019, 12, 31, 14, 26, 21, 658430) datetime.date(2019, 12, 31)
类date和类time可以从类datetime中分离出来,也可以通过combine方法合并成新的类datetime变量。
dt = datetime.now() # 获取当前日期时间
dt
dt.date() # 提取日期部分
dt.time() # 提取时间部分
datetime.combine(dt.date(),dt.time()) # 合并日期和时间
执行结果:
datetime.datetime(2019, 12, 31, 14, 28, 36, 804160) datetime.date(2019, 12, 31) datetime.time(14, 28, 36, 804160) datetime.datetime(2019, 12, 31, 14, 28, 36, 804160)
除了直接以参数形式创建时间和获取当前时间这两种方式之外,还有三种通过其他形式的时间格式转换的方法可以创建时间:
其中时间戳最小单位为秒,包含了日期和时间的信息;ISO日历公历序数最小单位为天,仅包含了日期的信息。这两种方法只适用于datetime对象和date对象,time对象无法使用。
fromisoformat方法三种类都可以使用,但是它有着固定的输入格式要求,如果是非标准格式的字符串,那么无法使用该方法,后面的strptime方法才可以装换非标准格式的时间。
## datetime datetime.fromtimestamp(1577777777.32452) # 时间戳转时间(以秒为单位) datetime.fromordinal(737425) # 多格勒公历序树转日期(以天为单位) datetime.fromisoformat("2020-01-01 12:00:00") # YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]]
## date date.fromtimestamp(1577784872) # 时间戳转时间(以秒为单位) date.fromordinal(739032) # 多格勒公历序树转日期(以天为单位) date.fromisoformat("2020-01-01") # 字符转时间,仅支持格式 YYYY-MM-DD,注意01的0也要有
## time time.fromisoformat("12:45:10") # 字符转时间,仅支持格式HH:MM:DD
执行结果:
datetime.datetime(2019, 12, 31, 15, 36, 17, 324520) datetime.datetime(2020, 1, 1, 0, 0) datetime.datetime(2020, 1, 1, 12, 0) datetime.date(2019, 12, 31) datetime.date(2024, 5, 26) datetime.date(2020, 1, 1) datetime.time(12, 45, 10)
datetime每一个类里面的参数,都是可以通过获取类属性的方式单独取出来的。
dt = datetime.today()
dt
dt.year
dt.month
dt.day
dt.hour
dt.minute
dt.second
dt.microsecond
执行结果:
2019 12 31 15 22 40 354681
修改替换时间中的时间参数,适用于三种类,例如:
dt = datetime.now()
dt
dt.replace(year=2020,day=15,hour=12)
执行结果:
返回time模块中的时间元组,适用于datetime对象和date对象,不适用于time对象,例如:
dt = datetime.now()
dt.timetuple()
执行结果:
datetime.datetime(2019, 12, 31, 15, 27, 5, 882867) time.struct_time(tm_year=2019, tm_mon=12, tm_mday=31, tm_hour=15, tm_min=27, tm_sec=5, tm_wday=1, tm_yday=365, tm_isdst=-1)
返回ISO公历序数,即从公元0年1月1日起到目标日期的天数。适用于datetime对象和date对象,不适用于time,例如:
dt = datetime.now()
dt.toordinal()
d = date.today()
d.toordinal()
执行结果:
737424 737424
返回时间戳,即从公元1970年1月1日0时0分0秒起,到目标时间的秒数。仅适用于datetime对象,不适用于time对象和date对象,例如:
dt = datetime.now()
dt.timestamp()
执行结果:
1577777225.882867
返回目标日期的工作日,0代表星期一,6代表星期日,适用于datetime对象和date对象,不适用于time对象,例如:
dt = datetime.now()
dt.weekday()
d = date.today()
d.weekday()
执行结果:
1 1
返回目标日期的工作日,1代表星期一,7代表星期日,它和weekday的区别仅仅在于起始序数的不同,适用于datetime对象和date对象,不适用于time对象,例如:
dt = datetime.now()
dt.isoweekday()
d = date.today()
d.isoweekday()
执行结果:
2 2
返回一个包含目标日期的年份、在一年中的第几周、周几三个元素在内的元组,适用于datetime对象和date对象,不适用于time,例如:
dt = datetime.now()
dt.isocalendar()
d = date.today()
d.isocalendar()
执行结果:
(2020, 1, 2) (2020, 1, 2)
返回一个标准化的时间字符串,适用三种类;datetime对象使用时返回完整的字符串,日期和时间的分隔部分默认为字符“T”,可设定;date对象使用时只返回日期部分的字符串,time对象使用时只返回时间部分的字符串,例如:
dt = datetime.now()
dt.isoformat() # 默认以字符“T”分隔日期和时间 dt.isoformat(sep=" ") # 以空格“ ”分隔日期和时间 d = date.today() d.isoformat() # 日期部分 t = datetime.now().time() t.isoformat() # 时间部分
执行结果:
'2019-12-31T15:27:05.882867' '2019-12-31 15:27:05.882867' '2019-12-31' '15:27:05.882867'
返回表示日期和时间的字符串,由明确的格式字符串控制,适用三种类。
详细的字符串格式如下所示:
格式含义示例%a工作日(缩写)Sun, Mon, …, Sat%A工作日(全称)Sunday, Monday, …, Saturday%w以十进制数表示的工作日,其中0是星期日,6是星期六。0,1,…,6%d月份中的一天,十进制数字表示。01,02,…,31%b月份,缩写名称。Jan, Feb, …, Dec%B月份,全名。January, February, …, December%m月份,十进制数字01,02,…,12%y年份(无世纪的年份,后两位),十进制数字。00,01,…,99%Y年份(四位完整),十进制数字。0001,0002,…,2013,2014,…,9998,9999%H小时(24小时制),十进制数字。00,01,…,23%I小时(12小时制)01,02,…,12%pAM或PMAM, PM%M分钟,十进制数字。00,01,…,59%S秒,以零填充的十进制数。00,01,…,59%f微秒,以零填充的十进制数。000000,000001,…,999999%zUTC偏移量的格式 ±HHMM[SS[.ffffff]](empty), +0000, -0400, +1030, +063415, -030712.345216%Z时区名称(empty), UTC, EST, CST%j一年中的一天,十进制数字。001,002,…,366%U一年中的第几周(星期日为一周的第一天),以零填充的十进制数表示。以周六所在年份为基准。00,01,…,53%W一年中的第几周(星期一为一周的第一天),以零填充的十进制数表示。以周日所在年份为基准00,01,…,53%c日期和时间Tue Aug 16 21:30:00 2019%x日期12/30/19%X时间17:24:13%%文字'%'字符。%%G年份,以零填充的十进制数表示。0001,0002,…,2013,2014,…,9998,9999%u工作日,十进制数字,其中1为星期一。1,2,…,7%V一年中的第几周(星期一为一周的第一天)。第01周是包含1月4日的一周。01,02,…,53
示例:
dt = datetime.now()
d = dt.date()
t = dt.time()
dt.strftime("%Y-%m-%d") # 常用日期一
d.strftime("%Y/%m/%d") # 常用日期二
t.strftime("%H:%M") # 时分
t.strftime("%p %I:%M") # 12时制时分
dt.strftime("%Y%m%d%H%M%S%f")+str(".txt") # 文件名 print("现在是北京时间{0}年{1}月{2}日,今天是{0}年的第{3}周,是{0}年的第{4}天".format(dt.strftime("%Y"),dt.strftime("%m"),dt.strftime("%d"),dt.strftime("%U"),dt.strftime("%j")))
执行结果:
'2019-12-31' '2019/12/31' '15:27' 'PM 03:27' '20191231152705882867.txt' 现在是北京时间2019年12月31日,今天是2019年的第52周,是2019年的第365天
将字符串解析为datetime指定格式的对象,由明确的格式字符串控制,与strftime方法相对应。其内部还是先调用的time模块中的striptime方法,获取struct_time对象,再利用struct_time对象中的年月日时分秒信息构建datetime对象。
strftime 即 string format time,用来将时间格式化成字符串
strptime 即string parse time,用来将字符串解析成时间。
strptime方法只适用于datetime对象。例如:
datetime.strptime("2020-01-01 12:00:00","%Y-%m-%d %H:%M:%S")
执行结果:
datetime.datetime(2020, 1, 1, 12, 0)
以上介绍的方法中:
在日常的实际使用中,我们经常需要对日期进行比较和加减运算。得益于python的操作符重载能力,python中可以方便地对date对象之间,或者datetime对象之间进行大小比较和减法(-)操作。
需要注意的是,这里仅限于同类对象之间的比较和减法运算,而且,不包括与time模块对象的比较和运算。datetime模块中的三个类,time对象仅能与同类做比较,不能进行任何运算,而date对象和datetime对象是可以和同中类型对象做减法运算的。
示例一:
## time对象只能同类做比较 time(21,2,4) >time(20,3,2)
# output1: True
## datetime对象可以比较,也可以做运算
dt = datetime(2019, 12, 31, 15, 22, 40, 354681)
dt - datetime(2019,1,1,0,0,0)
dt > datetime(2020,1,1,0,0,0)
# output2: datetime.timedelta(days=363, seconds=62653, microseconds=913011)
# output3: False
## date对象可以比较,也可以做运算 date(2020,1,1) - date(2019,1,1) date(2020,1,1) > date(2019,12,31)
# output4: datetime.timedelta(days=365)
# output5: True
datetime模块中三种对象的比较运算对比:
类能否同类比较能否同类作运算(仅减法)能否和timedelta类进行运算datetime能能能date能能能time能不能不能
从示例中可以看到,datetime对象和date对象同类中做减法返回的结果是datetime.timedelta对象,而这个就是datetime模块中专门用于时间运算的类。个人认为,类timedelta是datetime模块中最有价值的一部分,需要重点学习一下。
timedelta对象表示持续时间,两个日期或时间之间的差,它一共有7个参数可以用来定义timedelta对象。
但不是所有参数都会保留显示,timedelta对象定义后,内部仅存储天(day),秒(seconds)和微秒(microseconds)。其余参数将按以下单位换算转换为天、秒、微秒:
相应的转换公式为:
它们之间的装换
示例:
t = timedelta(50,27,10,29000,7,8,2) # output: datetime.timedelta(days=64, seconds=29276, microseconds=10)
timedelta对象进行多种合理的时间运算,如timedelta对象间加减法,timedelta对象与数值的乘除法运算。
示例二:
## timedelta对象可以进行的运算 t = timedelta(50,27,10,29000,7,8,2) d = timedelta(5,3,234,324,35,16,0) t + d # timedelta对象间加减法 t - d t * 2.3 # timedelta对象与数值乘除法 t / 2.8
示例三:
t // 2 # timedelta对象整除,返回timedelta对象 t // d # timedelta对象间整除,返回整数 t / d # timedelta对象间相除,返回float t % d # timedelta对象间相除取余数,返回timedelta对象 divmod(t,d) # 求模
执行结果:
datetime.timedelta(days=32, seconds=14638, microseconds=5) 11 11.305345573308651 datetime.timedelta(days=1, seconds=63739, microseconds=433436)
(11, datetime.timedelta(days=1, seconds=63739, microseconds=433436))
可以用total_seconds()方法获得一个timedelta对象的秒数表示,可用于和时间戳进行运算。
timedelta.total_seconds(t) t.days * 86400 + t.seconds + t.microseconds/1000000 # output1: 5558876.00001 # output2: 5558876.00001
timedelta对象含有三个属性:days,seconds, microseconds,days属性可以取负值,另外两个属性都只能是正值。示例
t = timedelta(days=27,seconds=47283,microseconds=123942)
t
n = -t # 去t的负数 n t + n # 等于0 t.seconds + n.seconds # 秒数相加等于86399 t.microseconds + n.microseconds # 微秒相加等于1,000,000 # timedelta对象也可以使用abs()函数求绝对值 abs(n) # 返回对应正数的timedelta对象
执行结果:
datetime.timedelta(days=27, seconds=47283, microseconds=123942) datetime.timedelta(days=-28, seconds=39116, microseconds=876058) datetime.timedelta(0) 86399 1000000 datetime.timedelta(days=27, seconds=47283, microseconds=123942)
前面提到的只是timedelta对象的一些基础内容,实际使用上更多的是和date对象或者datetime对象进行计算,计算主体是date对象或者datetime对象,timedelta对象作为辅助。
示例:
# date运算 date(2020,1,1) - timedelta(days=100) date(2020,1,1) + timedelta(days=100)
# datetime运算
dt = datetime(2020,2,22,20,2,2)
dt
dt + timedelta(days=20,seconds=4023)
dt - timedelta(days=20,seconds=4023)
执行结果:
# date运算结果 datetime.date(2019, 9, 23) datetime.date(2020, 4, 10)
# datetime运算结果 datetime.datetime(2020, 2, 22, 20, 2, 2) datetime.datetime(2020, 3, 13, 21, 9, 5) datetime.datetime(2020, 2, 2, 18, 54, 59)
通过以上对datetime模块的各种对象的详细介绍,相信足以对它的各种操作有了比较完整的了解,这些都是基础的示例运用,更进一步的使用要通过实际运用中各种不一样的需求来实践。
数据分析咨询请扫描二维码
《Python数据分析极简入门》 第2节 4 Pandas条件查询 在pandas中,可以使用条件筛选来选择满足特定条件的数据 importpanda ...
2024-11-22数据分析师的工作内容涉及多个方面,主要包括数据的收集、整理、分析和可视化,以支持商业决策和问题解决。以下是数据分析师的一 ...
2024-11-21数据分析师必须掌握的技能可以从多个方面进行归纳和总结。以下是数据分析师需要具备的主要技能: 统计学基础:数据分析师需要 ...
2024-11-21数据分析入门的难易程度因人而异,总体来看,入门并不算特别困难,但需要一定的学习和实践积累。 入门难度:数据分析入门相对 ...
2024-11-21数据分析是一项通过收集、整理和解释数据来发现有用信息的过程,它在现代社会中具有广泛的应用和重要性。数据分析能够帮助人们更 ...
2024-11-21数据分析行业正在迅速发展,随着技术的不断进步和数据量的爆炸式增长,企业对数据分析人才的需求也与日俱增。本文将探讨数据分析 ...
2024-11-21数据分析的常用方法包括多种技术,每种方法都有其特定的应用场景和优势。以下是几种常见的数据分析方法: 对比分析法:通过比 ...
2024-11-21企业数字化转型是指企业利用数字技术对其业务进行改造和升级,以实现提高效率、降低成本、创新业务模式等目标的过程。这一过程不 ...
2024-11-21数据分析作为一个备受追捧的职业领域,吸引着越来越多的女性加入其中。对于女生而言,在选择成为一名数据分析师时,行业选择至关 ...
2024-11-21大数据技术专业主要学习计算机科学、数学、统计学和信息技术等领域的基础理论和技能,旨在培养具备大数据处理、分析和应用能力的 ...
2024-11-21《Python数据分析极简入门》 第2节 3 Pandas数据查看 这里我们创建一个DataFrame命名为df: importnumpyasnpi ...
2024-11-21越老越吃香的行业主要集中在需要长时间经验积累和专业知识的领域。这些行业通常知识更新换代较慢,因此随着年龄的增长,从业者能 ...
2024-11-20数据导入 使用pandas库的read_csv()函数读取CSV文件或使用read_excel()函数读取Excel文件。 支持处理不同格式数据,可指定分隔 ...
2024-11-20大数据与会计专业是一门结合了大数据分析技术和会计财务理论知识的新型复合型学科,旨在培养能够适应现代会计业务新特征的高层次 ...
2024-11-20要成为一名数据分析师,需要掌握一系列硬技能和软技能。以下是成为数据分析师所需的关键技能: 统计学基础 理解基本的统计概念 ...
2024-11-20是的,Python可以用于数据分析。Python在数据分析领域非常流行,因为它拥有丰富的库和工具,能够高效地处理从数据清洗到可视化的 ...
2024-11-20在这个数据驱动的时代,数据分析师的角色变得愈发不可或缺。他们承担着帮助企业从数据中提取有价值信息的责任,而这些信息可以大 ...
2024-11-20数据分析作为现代信息时代的支柱之一,已经成为各行业不可或缺的工具。无论是在商业、科研还是日常决策中,数据分析都扮演着至关 ...
2024-11-20数字化转型已成为当今商业世界的热点话题。它不仅代表着技术的提升,还涉及企业业务流程、组织结构和文化的深层次变革。理解数字 ...
2024-11-20在现代社会的快速变迁中,选择一个具有长期增长潜力的行业显得至关重要。了解未来发展前景好的行业不仅能帮助我们进行职业选择, ...
2024-11-20