python中有两个和时间相关的模块time和datetime,我自己在使用的时候经常搞混。这一篇就来记录下这两个模块常见的一些功能。

time模块和datetime模块

time是python的内建模块,用与和时间相关的一些操作;datetime模块是第三方模块,为了方便操作,将和date与time相关的一些操作进行了封装。

所以本质上来讲,能用datetime来操作的都能用time来实现,通过后面的对比就能看到datetime模块确实方便很多。

时间的表示

首先要明确,python使用一个9元素的元组来表示时间,如下

元素

含义

取值范围

tm_year

1970-2038

tm_mon

1-12

tm_mday

1-31

tm_hour

小时

0-23

tm_min

分钟

0-59

tm_sec

0-60(60或61 是闰秒)

tm_wday

周几

0-6(0为周一)

tm_yday

一年的第几天

1-366(儒略历)

tm_isdst

夏令时标记位

-1,0,1

将这9个数组成的元组传递到

time.struct_time

类中,就构成了python中的时间对象,也就是一个struct_time对象。

个性化这9个数就构成了代表不同时间的struct_time对象,同时还可以将struct_time对象与字符串按照特定格式去相互转换,或者转为时间戳。

通过修改初始化参数去操作时间还是很不方便的,例如计算类似获取7天后的时间或者5小时前的时间这种偏移类的计算。而datetime模块对struct_time对象进行了封装,使得操作更加便捷。

time模块操作

下面先来看看time模块的使用,首先是我们最常用的两个操作

>>> time.time() # 获取当前时间戳

1603451939.5721555

>>> time.sleep(2) # 程序休眠2秒

下面我们构建上面提到的struct_time对象,既可以传递包含9个元素的元组来构建

>>> time.struct_time((2020,10,23,19,22,10,4,297,0))

time.struct_time(tm_year=2020, tm_mon=10, tm_mday=23, tm_hour=19, tm_min=22, tm_sec=10, tm_wday=4, tm_yday=297, tm_isdst=0)

也可以直接通过时间戳来转换

>>> time.localtime(time.time())

time.struct_time(tm_year=2020, tm_mon=10, tm_mday=23, tm_hour=19, tm_min=22, tm_sec=7, tm_wday=4, tm_yday=297, tm_isdst=0)

有了struct_time对象就可以进行格式化输出了

>>> a=time.localtime(time.time())

>>> time.strftime('%Y-%m-%d|%H:%M:%S',a)

'2020-10-23|19:25:46'

strftime()

方法接受两个参数,一个字符串和一个struct_time对象,其中字符串内可以通过百分号来进行格式输出,常见的几种格式如下,完整的格式可以查看

这里

格式

含义

%Y

四位数表示的年份

%y

两位数表示的年份

%m

月份

%d

一月内的第几天

%H

24小时制小时数

%M

分钟数

%S

秒数

%Z

时区

既然可以从struct_time对象格式化为字符串,当然也可以反过来从字符串按照特定格式提取struct_time对象

>>> b=time.strptime('2020|10|23||20|05|10','%Y|%m|%d||%H|%M|%S')

>>> b

time.struct_time(tm_year=2020, tm_mon=10, tm_mday=23, tm_hour=20, tm_min=5, tm_sec=10, tm_wday=4, tm_yday=297, tm_isdst=-1)

有个很常见的场景,就是从网络上爬虫下来的时间可能是各种格式的,就可以用这种方式来处理。

datetime模块操作

查看一下源码就会发现,在

datetime.py

文件中,定义了5个类,分别是

timedelta

time

datetime

date

timezone

所以,

from datetime import xxx

之后只可能产生这5种对象,不会再有上面所说的struct_time对象了。

通常使用

datetime

类就够了

>>> import datetime

>>> datetime.datetime.__doc__

'datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])...'

可以看到至少要传递3个参数,分别是年月日

>>> a=datetime.datetime(2020,2,14)

>>> a

datetime.datetime(2020, 2, 14, 0, 0)

像分别得到

date

time

对象也很容易

>>> a.date()

datetime.date(2020, 2, 14)

>>> a.time()

datetime.time(0, 0)

当然通常是通过当前时间做一个偏移来得到想要的时间,也就是time模块比较难实现的部分

>>> b=a+datetime.timedelta(days=5)

>>> b

datetime.datetime(2020, 2, 19, 0, 0)

这里的

timedelta

专门用来生成时间偏移对象,通过下面的可以看到除了表示天数差异的

days

,也可以进行其余6种级别的偏移

>>> datetime.timedelta.__doc__

'Difference between two datetime values.\n\ntimedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)\n\nAll arguments are optional and default to 0.\nArguments may be integers or floats, and may be positive or negative.'

而表示当前时间的

datetime

对象也可以直接获取

>>> now=datetime.datetime.now()

>>> now

datetime.datetime(2020, 10, 23, 23, 44, 15, 822505)

>>> today=datetime.date.today()

>>> today

datetime.date(2020, 10, 23)

至于字符串的格式输出和格式提取所用到的关键字和上面一样

>>> datetime.datetime.strptime('2020>10>23>23>50>10','%Y>%m>%d>%H>%M>%S')

datetime.datetime(2020, 10, 23, 23, 50, 10)

>>> datetime.datetime(2020,10,23,23,50,11).strftime('%Y

'2020<10<23<23<50<11'

最后是和时间戳之间的相互转换

>>> datetime.datetime(2020,10,23,23,50,11).timestamp()

1603468211.0

>>> datetime.datetime.fromtimestamp(1603468213.3)

datetime.datetime(2020, 10, 23, 23, 50, 13, 300000)

Mysql存储

Mysql中有如下几个时间相关的字段

字段

格式

date

YYYY-MM-DD

time

HH:MM:SS

year

YYYY

datetime

YYYY-MM-DD HH:MM:SS

timestamp

YYYYMMDD HHMMSSS

如果要用原生SQL语句去进行Insert操作,需要用

strftime

将datetime对象转变为指定格式的字符串然后存储,不然会有格式报错。

但既然是python操作,那么经常使用的是通过ORM来操作,下面以Django为例来做一下演示。

首先在models中创建一个测试用的表

class DateTest(models.Model):

dt = models.DateTimeField()

d = models.DateField()

class Meta:

db_table = 'DateTest'

迁移完成。

然后创建如下的路由和视图函数

path('test/', views.insert_date, name='test'),

def insert_date(request):

date_obj = DateTest(dt=datetime.datetime.now(), d=datetime.date.today())

date_obj.save()

return HttpResponse('数据插入成功')

可以看到Django中非常贴心的将ORM中的

DateTimeField

DateField

与python中的datetime和date数据类型进行了一一对应,直接将python对象赋值给对应字段即可。

如果访问上述url数据库中成功加入一条记录如下


点击选中对应的记录可以看到对应的SQL语句如下

INSERT INTO cmdb.DateTest (id, dt, d) VALUES (1, '2020-10-24 12:17:36.572617', '2020-10-24');

可以看到SQL中是以特定格式字符串来插入的。

我是T型人小付,一位坚持终身学习的互联网从业者。如果有问题欢迎在底下的评论区交流,谢谢。