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模块的各种对象的详细介绍,相信足以对它的各种操作有了比较完整的了解,这些都是基础的示例运用,更进一步的使用要通过实际运用中各种不一样的需求来实践。
数据分析咨询请扫描二维码
在如今的数据驱动时代,掌握数据分析的工具和方法不仅是提高工作效率的关键,也是开拓职业机会的重要技能。数据分析涉及从数据的 ...
2024-11-08在现代商业环境中,企业正在逐步认识到数据挖掘技术在客户行为分析中的重要性。通过深度分析客户数据,这项技术不仅可以帮助企业 ...
2024-11-08数据挖掘分析是从大量数据中发现隐藏模式和有用信息的过程。尤其是在图数据挖掘中,提供了分析复杂关系和结构的独特视角。图数据 ...
2024-11-08在当今快速发展的商业环境中,提高运营效率已成为企业取得成功的关键因素。企业需要通过优化工作流程、利用技术创新和提升员工技 ...
2024-11-08Python 是一门非常适合初学者学习的编程语言。其简洁明了的语法、丰富的功能库,以及广泛的应用领域,使其成为学习编程的理想选 ...
2024-11-08在当今快速变化的商业环境中,金融数字化已经成为中小企业(SMEs)发展的关键驱动力。通过采用数字工具和技术,中小企业能够提高 ...
2024-11-08中小企业在全球经济中扮演着重要角色,然而,面对数字化浪潮,这些企业如何有效转型成为一大挑战。数字化转型不仅是技术的升级, ...
2024-11-08选择合适的数据分析方法是数据分析流程中的关键环节。它影响最终结论的准确性和可信度。在这个过程中,需要综合考虑数据的性质、 ...
2024-11-08在当今数据驱动的商业环境中,数据分析师扮演着至关重要的角色。他们帮助企业从大量数据中提取有用的洞察,从而推动决策制定和战 ...
2024-11-07在现代商业环境中,商务数据分析师扮演着至关重要的角色。作为联系业务需求与数据洞察之间的桥梁,数据分析师需要具备一系列技能 ...
2024-11-07在现代商业环境中,商务数据分析师扮演着至关重要的角色。作为联系业务需求与数据洞察之间的桥梁,数据分析师需要具备一系列技能 ...
2024-11-07在现代商业环境中,数据挖掘发挥着至关重要的作用。它不仅帮助企业从庞大的数据集中提取有价值的信息,还为企业的决策和业务运营 ...
2024-11-07数据分析可视化是一种通过图形化方式展现数据的技术,它使复杂的数据变得直观易懂,从而帮助我们更好地做出决策。在这个快速发展 ...
2024-11-07数据分析是一项至关重要的技能,尤其在当今数据驱动的世界中。Python以其强大的库和简单的语法成为了数据分析领域的佼佼者。本文 ...
2024-11-07在现代数据驱动的环境中,数据分析师扮演着至关重要的角色。他们需要掌握多种工具,以满足数据分析、处理和可视化的需求。无论是 ...
2024-11-07作为一名业务分析师,你将发现自己处于企业决策和数据驱动战略之间的桥梁位置。这个角色要求掌握一系列技能,以便有效地将数据转 ...
2024-11-07CDA中科院城市环境研究所(厦门)内训圆满成功 2017年9月12日-15日,CDA数据分析师在中科院城市环境研究所(厦门)进行了 ...
2024-11-07数据分析是现代商业和研究领域不可或缺的重要工具。无论是为了提高业务决策的准确性,还是为了发掘隐藏在数据中的潜在价值,了解 ...
2024-11-06数据分析是一个精细且有序的过程,旨在从海量数据中提取有用的信息,为决策提供有力支持。无论你是新手还是有经验的分析师,理解 ...
2024-11-06在当今竞争激烈的商业环境中,业务分析师(Business Analyst, BA)的角色变得愈加重要。随着企业对数据驱动决策的依赖加深,业务 ...
2024-11-06