time,datetime
dateutil、dateparser
timeit,深入理解list()和[]区别
在项目中经常要用到时间,日期等数据,这里做对常用的库及方法进行简单的总结
time
time模块中时间表现的格式主要有三种:
- timestamp:时间戳,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量
- struct_time:时间元组(tm_year,tm_mon,tm_mday,tm_hour,tm_min,tm_sec,tm_wday,tm_yday,tm_isdst)
- format_time:格式化时间。已格式化的结构使时间更具可读性
import time
time_start = time.time()
perf_counter_start = time.perf_counter()
process_start = time.process_time()
print(1, list(filter(lambda x: x if not x.startswith('_') and not x.isupper() else '', sorted(list(time.__dict__.keys())))))
# 生成timestamp
print(2, time.time())
# struct_time to timestamp
print(3, time.mktime(time.localtime()))
# 生成struct_time
# timestamp to struct_time 本地时间
print(4, time.localtime())
print(5, time.localtime(time.time()))
# timestamp to struct_time 格林威治时间
print(6, time.gmtime())
print(7, time.gmtime(time.time()))
# format_time to struct_time
print(8, time.strptime('2020-05-05 16:37:06', '%Y-%m-%d %X'))
# 生成format_time
# struct_time to format_time
print(9, time.strftime("%Y-%m-%d %X"))
print(10, time.strftime("%Y-%m-%d %X", time.localtime()))
print(11, time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()))
"""
%Y Year with century as a decimal number.
%m Month as a decimal number [01,12].
%d Day of the month as a decimal number [01,31].
%H Hour (24-hour clock) as a decimal number [00,23].
%M Minute as a decimal number [00,59].
%S Second as a decimal number [00,61].
%z Time zone offset from UTC.
%a Locale's abbreviated weekday name.
%A Locale's full weekday name.
%b Locale's abbreviated month name.
%B Locale's full month name.
%c Locale's appropriate date and time representation.
%I Hour (12-hour clock) as a decimal number [01,12].
%p Locale's equivalent of either AM or PM.
Other codes may be available on your platform.
See documentation for the C library strftime function.
"""
# 生成固定格式的时间表示格式
print(12, time.asctime(time.localtime()))
print(13, time.ctime(time.time()))
# 其他
time.sleep(1)
time_end = time.time()
perf_counter_end = time.perf_counter()
process_end = time.process_time()
# 计算执行时间
print(14, time_end - time_start)
print(15, perf_counter_end - perf_counter_start)
print(16, process_end - process_start) # 不包括sleep()休眠时间期间经过的时间,上面两个包含
datetime
datatime模块重新封装了time模块,提供更多接口,提供的类有:date,time,datetime,timedelta,tzinfo,timezone
类名称 | 描述 |
---|---|
datetime.date | 表示日期,常用的属性有:year, month和day |
datetime.time | 表示时间,常用属性有:hour, minute, second, microsecond |
datetime.datetime | 表示日期时间 |
datetime.timedelta | 表示两个date、time、datetime实例之间的时间间隔,分辨率(最小单位)可达到微秒 |
datetime.tzinfo | 时区相关信息对象的抽象基类。它们由datetime和time类使用,以提供自定义时间的而调整。 |
datetime.timezone | Python 3.2中新增的功能,实现tzinfo抽象基类的类,表示与UTC的固定偏移量 |
date类
- datetime.date(year, month, day)
# print(13, time_end - time_start)
# print(14, perf_counter_end - perf_counter_start)
# print(15, process_end - process_start)
# t1 = time.localtime()
# t2 = time.localtime(12344)
# print(t1)
# print(t2)
# print(t1 + t2)
# from datetime import date, time, datetime, timedelta, tzinfo, timezone
import datetime
import time
'''
date.today():返回一个表示当前本地日期的date对象;
date.fromtimestamp(timestamp):根据给定的时间戮,返回一个date对象
'''
today = datetime.date.today()
print(today, type(today))
today_fromtimestamp = datetime.date.fromtimestamp(time.time())
print(today_fromtimestamp, type(today_fromtimestamp))
'''
d1 = datetime.date(2019, 11, 1)
d1.year、date.month、date.day:年、月、日;
d1.replace(year, month, day):生成一个新的日期对象,用参数指定的年,月,日代替原有对象中的属性。(原有对象仍保持不变)
d1.timetuple():返回日期对应的time.struct_time对象;
d1.weekday():返回weekday,如果是星期一,返回0;如果是星期2,返回1,以此类推;
d1.isoweekday():返回weekday,如果是星期一,返回1;如果是星期2,返回2,以此类推;
d1.isocalendar():返回格式如(year,month,day)的元组;
d1.isoformat():返回格式如'YYYY-MM-DD’的字符串;
d1.strftime(fmt):和time模块format相同。
'''
today_date = datetime.date(2019, 11, 1)
print(today_date.year, today_date.month, today_date.day)
tomorrow_date = today_date.replace(2019, 11, 2)
print(tomorrow_date, tomorrow_date.timetuple(), tomorrow_date.weekday(), tomorrow_date.isoweekday(), tomorrow_date.isocalendar(), tomorrow_date.isoformat(), tomorrow_date.strftime('%Y_%m_%d') )
time类
- class datetime. time ( hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0 ) 参数可选
import datetime
import time
'''
t1 = datetime.time(10,23,15) #time对象
t1.hour、t1.minute、t1.second、t1.microsecond:时、分、秒、微秒;
t1.tzinfo:时区信息;
t1.replace([ hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] ):创建一个新的时间对象,用参数指定的时、分、秒、微秒代替原有对象中的属性(原有对象仍保持不变);
t1.isoformat():返回型如"HH:MM:SS"格式的字符串表示;
t1.strftime(fmt):同time模块中的format;
'''
now_time = datetime.time(12, 24, 36, 59)
print(now_time.hour, now_time.minute, now_time.second, now_time.microsecond)
next_time = now_time.replace(12, 25, 36, 59)
print(next_time, next_time.isoformat(), next_time.strftime('%H:%M:%S'))
datetime类
- datetime相当于date和time结合起来
- datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
import datetime
import time
'''
datetime.today():返回一个表示当前本地时间的datetime对象;
datetime.now([tz]):返回一个表示当前本地时间的datetime对象,如果提供了参数tz,则获取tz参数所指时区的本地时间;
datetime.utcnow():返回一个当前utc时间的datetime对象;#格林威治时间
datetime.fromtimestamp(timestamp[, tz]):根据时间戮创建一个datetime对象,参数tz指定时区信息;
datetime.utcfromtimestamp(timestamp):根据时间戮创建一个datetime对象;
datetime.combine(date, time):根据date和time,创建一个datetime对象;
datetime.strptime(date_string, format):将格式字符串转换为datetime对象;
'''
today_datetime = datetime.datetime.today()
print(today_datetime, type(today_datetime))
now_datetime = datetime.datetime.now()
print(now_datetime, datetime.datetime.utcnow(), datetime.datetime.fromtimestamp(time.time()))
print(now_datetime.year, now_datetime.month, now_datetime.day, now_datetime.hour, now_datetime.minute, now_datetime.second)
print(datetime.datetime.now().date()) # 获取date对象
print(datetime.datetime.now().time()) # 获取time对象
获取到date,time对象后则可以用date类和time类的相关方法和属性
timedelta类
使用timedelta可以很方便的在日期上做天days,小时hour,分钟,秒,毫秒,微妙的时间计算(如果要计算月份则可用下面的dateutil库来解决)
import datetime
import time
start_time = datetime.datetime.now()
today_datetime = datetime.datetime.now()
'''
datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0):在日期上做计算
datetime.timedelta.day, datetime.timedelta.seconds, datetime.timedelta.microseconds : 时间差的day, seconds,microseconds 数
datetime.timedelta.total_seconds():时间差的总秒数
'''
yesterday_datetime_1 = today_datetime + datetime.timedelta(days=-1, hours=1) # 昨天此时一个小时后
yesterday_datetime_2 = today_datetime - datetime.timedelta(days=1) # 昨天此时
tomorrow_datetime = today_datetime + datetime.timedelta(days=1) # 明天此时
print(yesterday_datetime_1, yesterday_datetime_2, tomorrow_datetime, sep='\n')
delta_datetime = today_datetime - yesterday_datetime_1 # 相差23个小时
print(delta_datetime, type(delta_datetime))
print(delta_datetime.days, delta_datetime.seconds, delta_datetime.total_seconds(), delta_datetime.microseconds)
time.sleep(1)
end_time = datetime.datetime.now()
delta_datetime = end_time - start_time # 计算执行时间
print(delta_datetime.total_seconds())
dateutil
The dateutil module provides powerful extensions to the standard datetime module, available in Python.
dateutil模块是python标准库datetime的增强版本,能够很方便计算相对时间(下一个月的,明年,下周一,一个月的最后一周等),计算两个给定时间的增量,而且能够解析几乎任何字符串格式的日期,时区处理等
dateutil安装
pip install python-dateutil
dateutil使用简介
from dateutil.relativedelta import *
from dateutil.easter import *
from dateutil.rrule import *
from dateutil.parser import *
from datetime import *
# now = datetime.now()
# now = parse("Sat Oct 11 17:13:46 UTC 2003")
now = parse("2028-11-5 15:33:12")
today = now.date()
year = rrule(YEARLY, dtstart=now, bymonth=8, bymonthday=13, byweekday=FR)[0].year
rdelta = relativedelta(easter(year), today)
print("Today is: %s" % today)
print("Year with next Aug 13th on a Friday is: %s" % year)
print("How far is the Easter of that year: %s" % rdelta)
print("And the Easter of that year is: %s" % (today + rdelta))
其他
- 如计算一个月后的的今天是周几
from dateutil.relativedelta import *
# from datetime import *
import datetime
today = datetime.datetime.now()
next_month = today + relativedelta(months=+1)
print(f"一个月后的今天是周{next_month.isoweekday()}")
更多使用方法可参考官方文档
dateparser
- 可以处理多种语言的几乎所有格式日期时间字符串
- 很容易处理相对时间
官方文档
dateparser安装
pip install dateparser
dateparser基本使用
- 基本使用
d1 = dateparser.parse('Fri, 12 Dec 2014 10:55:50')
d2 = dateparser.parse('1991-05-17')
# 相对时间处理如 '1 min ago', '2 weeks ago', '3 months, 1 week and 1 day ago', 'in 2 days', 'tomorrow'
d3 = dateparser.parse('In two months')
d4 = dateparser.parse('1484823450') # timestamp时间戳处理
print(d1, d2, d3, d4)
- 多语言支持
d5 = dateparser.parse('2小时前')
d6 = dateparse.parse('明天')
print(d5, d6)
- settings参数
d7 = dateparser.parse('14-10-20', settings={'DATE_ORDER': 'YMD'})
d8 = dateparser.parse('14-10-20', settings={'DATE_ORDER': 'MDY'})
print(d7, d8)
这里仅举例了日期顺序的设置,还可以处理其他settings如不完整日期,可进一步参考官方文档
- dateparser.parse返回的对象类型
d1 = dateparser.parse('2020-05-17')
print(d1, type(d1), sep='\n)
------------------
2020-05-17 00:00:00
<class 'datetime.datetime'>
由上可知,dateparser.parse返回的是datetime.datetime对象,根据需要可利用datetime.datetime的函数和属性进一步处理
d1 = dateparser.parse('2020-05-17 12:23:23')
print(d1.year, d1.time())
timeit
- 用来测试小段代码的运行时间
- 主要通过timeit和repeat两个函数实现,源码如下:
# timeit和repeat源码,都是调用了Timer对象的timeit或repeat函数
def timeit(stmt="pass", setup="pass", timer=default_timer,
number=default_number, globals=None):
"""Convenience function to create Timer object and call timeit method."""
return Timer(stmt, setup, timer, globals).timeit(number)
def repeat(stmt="pass", setup="pass", timer=default_timer,
repeat=default_repeat, number=default_number, globals=None):
"""Convenience function to create Timer object and call repeat method."""
return Timer(stmt, setup, timer, globals).repeat(repeat, number)
stmt:用于传入要测试时间的代码,可以直接接受字符串的表达式,也可以接受单个变量,也可以接受函数。传入函数时要把函数申明在当前文件中,然后在
stmt = 'func()'
执行函数,然后使用setup = 'from __main__ import func'
setup:传入stmt的运行环境,比如stmt中使用到的参数、变量,要导入的模块等。可以写一行语句,也可以写多行语句,写多行语句时要用分号;
隔开语句。
number:要测试的代码的运行次数,默认100000次
repeat:指测试要重复几次,每次的结果构成列表返回,默认3次
import timeit
# stmt为字符串表达式
print(timeit.timeit(stmt='list(i**2 for i in normal_list)', setup='normal_list=range(10000)', number=10))
print(timeit.timeit(stmt='list(i**2 for i in range(10000))', number=10))
print(timeit.repeat(stmt='list(i**2 for i in normal_list)', setup='normal_list=range(10000)', repeat=2, number=10))
# setup 为复合语句
print(timeit.timeit(stmt='list(i**2 for i in normal_list)', setup='a=10000;normal_list=range(a)', number=10))
print(timeit.repeat(stmt='list(i**2 for i in normal_list)', setup='a=10000;normal_list=range(a)', repeat=2, number=10))
def func():
normal_list = range(10000)
lst = [i ** 2 for i in normal_list]
# stmt为函数
print(timeit.timeit("func()", setup="from __main__ import func", number=10))
print(timeit.repeat("func()", setup="from __main__ import func", repeat=2, number=10))
timeit机制
- 从内部讲,timeit 构建起一个独立的虚拟环境,手工地执行建立语句 (导入 soundex 模块),然后手工地编译和执行被计时语句 (调用 Soundex 函数)
- 可以说使用timeit计时更准确,切勿自己编写计时函数。在程序中有很多因素会影响计算的时间,比如垃圾回收机制。使用timeit会自动关掉垃圾回收机制,让程序的运行更加独立,时间计算更加准确
在jupyter notebook中使用timeit
可在jupyter notebook中执行%timeit?
查看具体使用方法
Usage, in line mode:
%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
or in cell mode:
%%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
[]
和list()
- list()是内置类型(built-in types)
- 内置函数built-in functions和内置类型built-in types 官方文档
- 内置函数和内置类型都不是关键字,可参看官方文档keywords
- Python 给一些常用的内置类型提供了字面量表示法,也就是
""、[]、()、{}
等等,表示字符串、列表、元组和字典等数据类型,参看官方文档delimiters
import timeit
print(timeit.timeit('[]', number=10 ** 7)) # 0.22205465100000002
print(timeit.timeit('list()', number=10 ** 7)) # 0.8627885369999999
- list() 比
[]
执行步骤多,因此list()比[]
慢(可通过dis模块的dis()函数查看两者字节码,[]
的字节码有两条指令(BUILD_LIST 与 RETURN_VALUE),而 list() 的字节码有三条指令(LOAD_NAME、CALL_FUNCTION 与 RETURN_VALUE))