2019年7月3日 / 5,447次阅读 / Last Modified 2019年11月13日
时间计算
Python datetime模块中有好几个与时间有关的类,而date类是专门用来处理日期的类,日期就是年月日,没有时分秒。本文介绍datetime.date类和对象的用法。
datetime.date对象在Python官方文档中,被称为naive object,我们可以理解为“单纯的对象”。如下是Python官方对naive object的说明:
A naive object does not contain enough information to unambiguously locate itself relative to other date/time objects. Whether a naive object represents Coordinated Universal Time (UTC), local time, or time in some other timezone is purely up to the program, just like it is up to the program whether a particular number represents metres, miles, or mass. Naive objects are easy to understand and to work with, at the cost of ignoring some aspects of reality.
翻译如下:
一个单纯的日期对象,即它自己不含有足够的信息,以便可以将自己与其它类似的date或time对象清晰地区分开来。一个单纯的日期对象,它表示的是UTC时间,本地时间,还是其它时区的时间,完全取决于程序代码。就像一个数字,它表示的是米,英里,还是其它什么,完全靠程序的解释。单纯的对象理解简单,使用方便,因它为忽略了一些现实的影响。
我喜欢用这种方式引入datetime.date类,因为date这个词足够特殊:
>>> from datetime import date
date类中,限制了最大和最小的年份,因此我们在创建date对象时,注意不要超过这个最大最小值,否则会有ValueError异常被抛出。
>>> date.min
datetime.date(1, 1, 1)
>>> date.max
datetime.date(9999, 12, 31)
>>> d1 = date(1998, 7, 13)
>>> d1.year
1998
>>> d1.month
7
>>> d1.day
13
>>> d1
datetime.date(1998, 7, 13)
公元1万年时,Python的date类就无法使用了!:)
以上高亮的第5行,就是一般创建date对象的方式,直接用年月日三个参数。除这种常规的方式,还有以下几种方式:
从POSIX时间戳(UNIX时间戳)创建date对象:
>>> import time
>>> d2 = date.fromtimestamp(time.time())
>>> d2
datetime.date(2019, 7, 2)
time.time()返回的是此函数调用时刻的POSIX时间戳。
从累计天数(从1年1月1日开始累计)创建date对象:
>>> date.fromordinal(10000)
datetime.date(28, 5, 18)
>>> date.fromordinal(100000)
datetime.date(274, 10, 16)
>>> date.fromordinal(1000000)
datetime.date(2738, 11, 28)
fromordinal
成员函数的参数是累计天数,这个累计天数是从公元1年1月1日开始计算的,包含了leap day(润月多的那一天,2月29日)。区区100万天,就已经到了2738年11月28日,人类的历史只是宇宙的一瞬间。date类还有一个toordinal
成员函数,将日期转换成累计天数,请看下面这个恒等式:
>>> date.fromordinal(date(2019,1,1).toordinal())
datetime.date(2019, 1, 1)
从ISO时间格式字符串创建date对象:
注意:fromisoformat
函数是Python3.7新增的:
>>> date.fromisoformat('2008-07-07')
datetime.date(2008, 7, 7)
>>> date.fromisoformat('2008-07-07').isoformat()
'2008-07-07'
需要注意的是ISO时间格式:YYYY-MM-DD,像7月7日这样的单数月和单数日,MM和DD首位是0。函数 isoformat
将一个date对象转换成ISO时间格式字符串,这种时间字符串很常用,并在低于Python3.7的版本中已经存在,比如用在每天生成的日志文件名称中,每天备份的数据库文件的名称中。
>>> date.today()
datetime.date(2019, 7, 3)
>>> date.today().isoformat()
'2019-07-03'
>>> date.today().toordinal()
737243
>>> today = date.today()
>>> today.year
2019
>>> today.month
7
>>> today.day
3
今天函数,就是名叫 today
的成员函数,它可以获取一个今天的年月日组成的date对象。用以上代码,可以获取当前日期的各种信息。还有另外一种获取今天日期的方式:
>>> today = date.fromtimestamp(time.time())
>>> today
datetime.date(2019, 7, 3)
星期函数,就是获取某个日期是星期几的函数:
>>> date.today()
datetime.date(2019, 7, 3)
>>> date.today().weekday()
2
>>> date.today().isoweekday()
3
函数 weekday
返回的星期从0-6,函数 isoweekday
返回的星期从1-7。
这个ISO日历函数,跟我们平常的认知有点区别。一个ISO年包含52或者53个完整的星期,从星期一开始,到星期天结束。因此ISO日历的年份与我们常用的公历的年份会有一些出入,请看下面的代码:
>>> date(1,1,1).isocalendar()
(1, 1, 1)
>>> date(1,12,31).isocalendar()
(2, 1, 1)
>>> date(2003,12,29).isocalendar()
(2004, 1, 1)
>>> date(2004,1,4).isocalendar()
(2004, 1, 7)
>>> date(2004,1,4).isoweekday()
7
isocalendar
函数返回的是一个tuple,内涵3个数据,分别是ISO年,第几个星期,星期几。这个函数得到星期,与 isoweekday
函数一致。
一个date对象包含了年月日,我们可以通过 replace
函数来修改年月日信息:
>>> date.today()
datetime.date(2019, 7, 3)
>>> date.today().replace(2000,2,29)
datetime.date(2000, 2, 29)
>>> date.today().replace(year=2009)
datetime.date(2009, 7, 3)
>>> date.today().replace(month=9)
datetime.date(2019, 9, 3)
>>> date.today().replace(day=9)
datetime.date(2019, 7, 9)
>>> date.today().replace()
datetime.date(2019, 7, 3)
date对象只包含年月日信息,没有时分秒,因此通过成员函数 ctime 得到的C语言时间格式,时分秒部分是全0:
>>> date.today().ctime()
'Wed Jul 3 00:00:00 2019'
通过 strftime
函数,我们可以获得自定义格式的日期:
>>> date.today().strftime('%Y_%m_%d')
'2019_07_03'
>>> date.today().strftime('%y_%B_%j')
'19_July_184'
>>> date.today().strftime('%x')
'07/03/19'
date类有 isoformat
格式的日期,而通过以上示例代码,我们可以得到更多日期格式,这部分可用的参数,请参考Python官网的说明:https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior
以上内容,应该足够让你掌握datetime.date对象的用法了。
-- EOF --
本文链接:https://www.pynote.net/archives/445
©Copyright 麦新杰 Since 2019 Python笔记