datetime是Python处理日期和时间的标准库
获取当前日期和时间
获取指定日期和时间
from datetime import datetime, timedelta, timezone
# 获取当前datetime:
now = datetime.now()
print('now =', now)
print('type(now) =', type(now))
# 用指定日期时间创建datetime:
dt = datetime(2015, 4, 19, 12, 20)
print('dt =', dt)
datetime与timestamp转换
timestamp的值与时区没有关系,因为timestamp一旦确定了,其UTC时间就确定了,转换到任意时区的时间也是完全确定的,这就是为什么计算机存储的当前时间是以timestamp表示的。
注:1、python的timestamp是一个浮点数,如果有小数位,小数位表示毫秒数
某些编程语言(如JAVA和JavaScript)的timestamp使用整数表示毫秒数,此时把timestamp除以1000就得到python的浮点表示方法
2、timestamp是一个浮点数,没有时区的概念,而datetime是有时区的
把datetime转换为timestamp调用timestamp( )方法
把timestamp转换为datetime,调用datetime的fromtimestamp( )方法,如果转换成带时区信息,即UTC+8这种形式,调用调用datetime的utcfromtimestamp( )方法
from datetime import datetime, timedelta, timezone
# 用指定日期时间创建datetime:
dt = datetime(2015, 4, 19, 12, 20)
print('dt =', dt)
# 把datetime转换为timestamp:
print('datetime -> timestamp:', dt.timestamp())
# 把timestamp转换为datetime:
t = dt.timestamp()
print('timestamp -> datetime:', datetime.fromtimestamp(t)) #本地时间
print('timestamp -> datetime as UTC+0:', datetime.utcfromtimestamp(t)) #UTC时间
datetime与str转换
当用户输入的日期和时间是字符串时,要处理日期和时间,必须先把str转换为datetime,方法:datetime.strptime( )实现
注意:转换后的datetime是没有时区信息的,即后面不带UTC+8这种形式
把datetime对象,格式化为字符串给用户,方法:strftime( )
from datetime import datetime, timedelta, timezone
# 从str读取datetime:
cday = datetime.strptime('2015-6-1 18:19:59', '%Y-%m-%d %H:%M:%S')
print('strptime:', cday)
# 把datetime格式化输出:
print('strftime:', cday.strftime('%a, %b %d %H:%M'))
datetime加减
即计算某个时间点一段时间间隔后的时间
方法:timedelta这个类,timedelta(days=3) , timedelta(hours=10), timedelta(days=1, hours=8)
1 # 对日期进行加减:
2 print('current datetime =', cday)
3 print('current + 10 hours =', cday + timedelta(hours=10))
4 print('current - 1 day =', cday - timedelta(days=1))
5 print('current + 2.5 days =', cday + timedelta(days=2, hours=12))
本地时间转换为UTC时间
本地时间是指系统设定时区的时间,例如北京时间是UTC+8:00时区的时间,而UTC时间是指UTC+0:00时区的时间
datetime类型有一个时区属性tzinfo,但默认是None,所以无法区分这个datetime到底是哪个时区,除非给datetime设置一个时区UTC形式
from datetime import datetime, timedelta, timezone
tz_utc_8 = timezone(timedelta(hours=8)) # 创建时区UTC+8:00
now = datetime.now() #当前时间,不带UTC形式
dt = datetime.now().replace(tzinfo=tz_utc_8) # 强制设置为UTC+8:00,带UTC形式
dt1 = datetime.now().replace(tzinfo=timezone(timedelta(hours=8)))
print("当前时间,不带UTC,不能确定是哪个时区:",now)
print("当前时间,带UTC,可以确定是哪个时区的时间:",dt)
print("当前时间,带UTC,可以直接写tzinfo:",dt1)
划红线的说明转换为UTC形式的时间了
时区转换
utcnow( )可以获得UTC+0:00时区的时间,再转换为任意时区的时间:
利用带时区的datetime,通过astimezone( )方法,可以转换到任意时区
注:不是必须从UTC+0:00时区转换到其他时区,任何带时区的datetime都可以正确转换,例如bj_dt到tokyp_dt的转换,依然是hours=9,而不是hours=1
# 把时间从UTC+0时区转换为UTC+8:
utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc)
bj_dt = utc_dt.astimezone(timezone(timedelta(hours=8)))
tokoy_dt = utc_dt.astimezone(timezone(timedelta(hours=9)))
tokoy1_dt = utc_dt.astimezone(timezone(timedelta(hours=9)))
print('UTC+0:00 now =', utc_dt)
print('UTC+8:00 now =', bj_dt)
print('UTC+9:00 now =', tokoy_dt)
print('从UTC+8:00转换为UTC+9:00 now =', tokoy1_dt)
实战
题目:假设你获取了用户输入的日期和时间,如2015-1-21 9:01:30,以及一个时区信息如UTC+5:00,均是str,请编写一个函数将其转换为timestamp:
from datetime import datetime, timezone, timedelta
def to_timestamp(dt_str, tz_str):
dt=datetime.strptime(dt_str,'%Y-%m-%d %H:%M:%S')
tz=int(tz_str[3:-3]) #获取+,包含+以及冒号之前的部分,这是 自己最初的想法
# tz=int(tz_str[3:].split(":")[0]) #第二种tz的计算方法,这是参考别人获得
dt1=dt.replace(tzinfo=timezone(timedelta(hours=tz)))
t=dt1.timestamp()
return t
t1 = to_timestamp('2015-6-1 08:10:30', 'UTC+7:00')
assert t1 == 1433121030.0, t1
t2 = to_timestamp('2015-5-31 16:10:30', 'UTC-09:00')
assert t2 == 1433121030.0, t2
print('ok')
collections模块
collections是Python内建的一个集合模块,提供了很多有用的集合类
collections模块中的集合类:namedtuple , deque, defaultdict, OrderedDict, ChainMap, Counter
namedtuple
namedtuple可以理解为一个函数,一个类,用来创建一个自定义的tuple对象(也可称为实例),并且规定了tuple元素的个数,可以用属性而不是索引来引用tuple的某个元素。
from collections import namedtuple
print("一个点的二维坐标:")
Point=namedtuple('Point',['x','y'])
p=Point(1,2)
print(p)
print(p.x)
print(p.y)
print("",'\n',"验证创建的Point对象是tuple的一种子类:")
print(isinstance(p,Point))
print(isinstance(p,tuple))
#namedtuple(名称,[属性List])
print("",'\n',"用坐标和半径表示一个圆:")
circle=namedtuple('circle',['x','y','z'])
deque
deque是能快速插入和删除的双向列表
deque能使用append( )和pop( ),还可以appendleft( )和popleft( ),这样可以在头部添加元素或从头部删除元素。deque不能使用pop( n )这种来删除元素,但list中可以
from collections import deque
d=deque(['a','b','c'])
print("最初的元素为:",d)
d.append('x')
print("默认将元素插入末尾:",d)
d.appendleft('y')
print("将元素插入到头部:",d)
d.pop()
print('默认删除末尾元素:',d)
d.popleft()
print('默认删除头部元素:',d)
defaultdict
使用dict时,如果引用的Key不存在,就会抛出KeyError错误。如果希望Key不存在时,返回一个默认值,就可以用defaultdict:
from collections import defaultdict
dd=defaultdict(lambda: 'N/A')
dd['a']=1
dd['b']=2
dd['c']=3
print(dd['c'])
print(dd['d']) #不存在这个Key,就会返回我们设置不存在时的默认值
OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序,如果要保持Key的顺序,可以使用OrderedDict
说明:
1、可以看出没有使用OrderedDict,每次运行时Key的排序都不同;而使用OrderedDict,每次运行时Key的排序都相同
2、OrderedDict对Key排序,是按照Key插入顺序排序的,而不是Key本身排序
1 from collections import OrderedDict
2 d=dict([('a',1),('b',2),('c',3)])
3 print(d)
4 od=OrderedDict([('d',1),('a',2),('c',3)])
5 print(od)
Counter
一个简单的计数器,Counter实际上也是dict的一个子类
from collections import Counter
c=Counter()
for ch in 'Programming':
c[ch]=c[ch]+1
print(c)