03.05时间管理第五章
@
使用场景
-
文件属性
-
数据库
-
页面UI显示
-
日志
-
时间戳(timestamp)
-
- 协调世界时
UTC
, 原子钟定义时间
- 协调世界时
-
- 时间戳指的是
Unix
时间戳, 定义为从格林威治时间1970年01月01日 00:00:00 起至今的总秒数
- 时间戳指的是
-
- 格林威治时间
GMT
- 格林威治时间
UTC
协调世界时(英语:Coordinated Universal Time,法语:Temps Universel Coordonné,简称UTC)是最主要的
世界时间标准,其以原子时秒长为基础,在时刻上尽量接近于格林尼治标准时间。''
东八区 : -> UTC + 8
西十区 : -> UTC - 10
代码中的时间
- 时间戳
timestamp
:1473525444
1525404023
- 时间字符串
Format String
:2015-02-14 10:25:00
- 结构化的时间
struct_time
:year=2018, month=5, day=1, hour=16, min=37, sec=6
常用时间模块
- time 用于获取时钟时间, 处理器运行时间耗时, 时间差
- datetime 支持算术, 比较和时区配置
- python-dateutil(pip install)
常用时间模块处理各种时间换算问题
常见操作
- 时间的各种表达格式类型
- 各种加减运算
常用方法 time.time()
以及 time.sleep()
time 对象
可以用 time(hour, min, sec, us)
产生一个 time
对象
import time
time.
time.
+ Tab按键
查看函数可用的方法, time.time
+ Shift
+ Tab
按键查看函数方法的用法
time.time()
1549953921.6927984
time.time() # 以秒为单位返回纪元以来的当前时间
1549953424.2878275
计算时间差, 获得秒数 示例
start = time.time()
print(start)
1539932049.6301212
end = time.time() # 计算时间差, 单位秒
print(f'过了{end - start} 秒')
过了54.78131175041199 秒
start = time.time()
# 执行各种操作, (倒数计时)
for i in range(10):
print(i)
end = time.time()
print(f'过了 {end - start} 秒')
0
1
2
3
4
5
6
7
8
9
过了 0.0 秒
时间休眠
time.sleep?
for i in range(6):
print(i)
for i in range(6):
time.sleep(2)
print(i)
0
1
2
3
4
5
结构化时间与时间戳的转换
time.localtime()
# http://devdocs.io/python~3.6/library/time#time.strftime
time.struct_time(tm_year=2019, tm_mon=2, tm_mday=13, tm_hour=15, tm_min=16, tm_sec=9, tm_wday=2, tm_yday=44, tm_isdst=0)
time.localtime(1339932049)
time.struct_time(tm_year=2012, tm_mon=6, tm_mday=17, tm_hour=19, tm_min=20, tm_sec=49, tm_wday=6, tm_yday=169, tm_isdst=0)
Index | Attribute | Values
- | - | - |
0 | tm_year | (for example, 1993)
1 | tm_mon | range [1, 12]
2 | tm_mday | range [1, 31]
3 | tm_hour | range [0, 23]
4 | tm_min | range [0, 59]
5 | tm_sec | range [0, 61]; see (2) in strftime() description
6 | tm_wday | range [0, 6], Monday is 0
7 | tm_yday | range [1, 366]
8 | tm_isdst | 0, 1 or -1; see below
N/A | tm_zone | abbreviation of timezone name
N/A | tm_gmtoff | offset east of UTC in seconds
time.mktime?
time.mktime(time.localtime())
1549977290.0
## 结构化时间与字符串格式的转换
## 时间的字符串格式化:http://devdocs.io/python~3.6/library/time#time.strftime
time.strftime?
datetime 格式字符表
字符 | 含义 |
---|---|
%Y |
完整的年份 |
%m |
月份,[01,12] |
%d |
日期,[01,31] |
%H |
小时,[00,23] |
%M |
分钟,[00,59] |
%S |
秒钟,[00,61] (大概是有闰秒的存在) |
%z |
Time zone offset from UTC. |
%a |
星期英文缩写 |
%A |
星期英文 |
%b |
月份英文缩写 |
%B |
月份英文 |
%c |
本地相应的日期和时间表示 |
%I |
小时,[01,12] |
%p |
AM 和 PM |
%X |
本地相应时间 |
上面是时间, 下面是日期
字符 | 含义 |
---|---|
%w |
一星期的第几天,[0(sun),6] |
%j |
一年的第几天,[001,366] |
%U |
一年中的第几个星期,星期日为第一天,[00,53] |
%W |
一年中的第几个星期,星期一为第一天,[00,53] |
%y |
没有世纪的年份 |
%x |
本地相应日期 |
## 结构化时间与字符串格式的转换
## 时间的字符串格式化
time.strftime("%Y-%m-%d %X", time.localtime())
'2019-02-12 21:24:28'
上面为当前时间(年-月-日 时:分:秒)的表达式,并以字符串格式化形式输出
time.strptime('2018-05-06 22:52:40', "%Y-%m-%d %X")
time.struct_time(tm_year=2018, tm_mon=5, tm_mday=6, tm_hour=22, tm_min=52, tm_sec=40, tm_wday=6, tm_yday=126, tm_isdst=-1)
time.strptime(string[, format])
:把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。
格式化字符串表示时间
strftime
: %
-> 1999-12-12
, 把代码里面的时间对象转成人类认识的字符串,f:format
strptime
: 2000-12-12
-> object
,把人类认识的字符串,转成代码里面的对象,p,parse
datetime模块的应用
http://devdocs.io/python~3.6/library/datetime
https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
import datetime
datetime.date.
from datetime import datetime
datetime.now()
datetime.datetime(2019, 2, 12, 21, 34, 3, 759331)
'{dt
:%Y-%m-%d}'.format(dt
=datetime.now())
注意引用的位置 (曾经使用的字符串格式化输出的类型)
'{dt:%Y-%m-%d}'.format(dt=datetime.now())
'2019-02-12'
f'{datetime.now():%Y-%m-%d}' # python 3.x常见写法
'2019-02-12'
from datetime import date
d = date(2035, 8, 8)
print(d)
2035-08-08
date.today()
datetime.date(2019, 2, 12)
print(date.today())
2019-02-12
from datetime import time
t = time(12, 4)
print(t)
12:04:00
# 时间的各种计算
from datetime import timedelta
d = timedelta(days=2) # 根据参数, 生成多少间隔周期的一个时间间隔对象
print(d)
2 days, 0:00:00
d =timedelta(hours=1)
print(d)
1:00:00
d = timedelta(days=6, hours=2)
print(d)
6 days, 2:00:00
today = date.today()
print(today)
2019-02-12
future = today + d
print(future)
2019-02-18
today = date.today()
print(type(today))
print(today.day)
print(today.month)
<class 'datetime.date'>
12
2
count = future - today
print(count)
type(count)
6 days, 0:00:00
datetime.timedelta
从时间戳生成datetime
import time
t = time.time()
print(t)
1549981583.6009007
from datetime import datetime
datetime.utcfromtimestamp(t)
datetime.datetime(2019, 2, 12, 14, 26, 23, 600901)
格式化字符串表示时间
strftime
: %
-> 1999-12-12
, 把代码里面的时间对象转成人类认识的字符串,f:format
strptime
: 2000-12-12
-> object
,把人类认识的字符串,转成代码里面的对象,p: parse(解析)
日期的不同输出方式
dt = datetime(2088, 8, 8, 8, 8)
print(dt)
2088-08-08 08:08:00
dt.strftime('%Y/%m%d %X')
'2088/0808 08:08:00'
dt.strftime('%A %B %Y')
'Sunday August 2088'
datetime.strptime('Sunday August 2088', '%A %B %Y')
datetime.datetime(2088, 8, 1, 0, 0)
datetime.strptime('2088-08-08 08:08:00', '%Y-%m-%d %X')
datetime.datetime(2088, 8, 8, 8, 8)
datetime.strptime('2088/08/08 08:08:00', '%Y/%m/%d %X')
datetime.datetime(2088, 8, 8, 8, 8)
dateutil
更好的控制日期
# pip install python-dateutil
# https://dateutil.readthedocs.io/en/stable/examples.html#relativedelta-examples
# timedelta不够用, 处理跨星期,跨月,跨年的计算麻烦
# class datetime.timedelta(days=0, seconds=0, microseconds=0,
# milliseconds=0, minutes=0, hours=0, weeks=0)
# 下周的星期三是几号
from datetime import datetime
from dateutil.relativedelta import relativedelta
from dateutil.rrule import * # MO,TU,WE,TH,FR
d = datetime.now()
print(d)
2019-02-19 21:24:27.763399
计算 从 d
开始的下个礼拜的星期三是几号
print(d + relativedelta(weekday=WE))
2019-02-13 23:30:24.795729
计算从d
开始的上一个礼拜的星期三是几号
print(d + relativedelta(weekday=WE, weeks=-1))
2019-02-06 23:30:24.795729
需求: 计算一个月, 三个月是哪天.
from datetime import date
date(2019,1,30) + relativedelta(months=+1)
datetime.date(2019, 2, 28)
date(2019,1,30) + relativedelta(months=+3)
datetime.date(2019, 4, 30)
date(2019,1,30) + relativedelta(months=-4)
datetime.date(2018, 9, 30)
date(2019,1,30) + relativedelta(years=-32)
datetime.date(1987, 1, 30)
案例: 时间转换器
给定随意的几种时间形式, 自动转成统一的格式
举例:
''2018/1/8 14:28', 4.7
, '2018年2月8日 14:28'
都能自动转成 2018-01-08 14:28:00
, 没有时间的自动添加当前时间
注意返回值,区分datetime类型
和str类型
from datetime import datetime
from dateutil import parser
d1 = '2019/1/8 14:28'
date1 = datetime.strptime(d1, '%Y/%m/%d %H:%M') # TODO 字符串转内置时间格式
print(type(date1))
print(date1)
date_str = date1.strftime('%Y-%m-%d %X')
print(type(date_str), date_str) # isinstance 方法
<class 'datetime.datetime'>
2019-01-08 14:28:00
<class 'str'> 2019-01-08 14:28:00
使用parser
快速搞定格式化输出
数字形式 年-月-日 小时:分钟:秒
d1 = '2019/1/23 14:28'
# d1 = '2019年2月8日 14:28'
date1 = parser.parse(d1)
print(type(date1))
print(date1)
<class 'datetime.datetime'>
2019-01-23 14:28:00
d2 = '2019/1/22'
date2 = parser.parse(d2)
print(date2)
2019-01-22 00:00:00
中文形式 年-月-日 小时:分钟:秒
d1 = '2019年1月29日 14:28'
d1.replace('年', '/').replace('月', '/').replace('日', '')
'2019/1/29 14:28'
输入的日期格式转为/
获得格式的字符串
只有日期, 没有时间
s = '1.6'
now = datetime.now()
my_time = now.replace(day=6, month=1) # 根据现有年月日复制缺少部分
# print(now, my_time)
my_time.strftime('%Y-%m-%d %X')
'2019-01-06 11:08:14'
封装函数
def change_datetime(dt):
"""将输入格式转成 yyyy-mm-dd hh:mm:ss"""
date1 = parser.parse(dt)
# date_str = date1.strftime()
date_str = date1.strftime('%Y-%m-%d %X')
print(type(date_str), date_str) # isinstance 方法
return date1, date_str
dt, dt_str = change_datetime('2014/3/20 2:10')
<class 'str'> 2014-03-20 02:10:00
dt_str
'2014-03-20 02:10:00'
def change_datetime_cn(dt):
# 中文格式的日期
date1 = dt.replace('年', '/').replace('月', '/').replace('日', '')
return change_datetime(date1) # 函数嵌套
change_datetime_cn('2019年1月2日')
<class 'str'> 2019-01-02 00:00:00
(datetime.datetime(2019, 1, 2, 0, 0), '2019-01-02 00:00:00')
dt_str
'2014-03-20 02:10:00'
1.1
格式的日期
def change_datetime_num(dt):
"""处理纯数字格式的日期 并自动添加时间"""
month, day = dt.split('.')
now = datetime.now()
my_time = now.replace(day=int(day), month=int(month))
print(now, my_time)
return now, my_time.strftime('%Y-%m-%d %X')
change_datetime_num('2.6') # 确保输入为字符串
2019-02-13 00:21:17.112677 2019-02-06 00:21:17.112677
(datetime.datetime(2019, 2, 13, 0, 21, 17, 112677), '2019-02-06 00:21:17')
# 抽象成类, TODO: 完善上面的函数,并添加你需要的任何格式转换
class TimeMaster:
def __init__(self, fmt='%Y-%m-%d %X'):
self._output_format = fmt
def change_datetime_num(self, dt):
"""转换'1.5'这种月日格式的日期,并添加时间"""
month, day = dt.split('.')
now = datetime.now()
# my_time = now.replace(day=day, month=month)
my_time = now.replace(day=int(day), month=int(month))
print(now, my_time)
return now, my_time.strftime(self._output_format)
def set_format(self, new_fmt):
self._output_format = new_fmt
项目 51备忘录v0.35
- 添加功能:根据输入内容,自动完成日期时间的添加
- 复习从第一行代码到写成类的整个过程
KV编程论:
-
只是一个思考框架,处理只是记忆的各种关联。
-
- 项目:拆解
-
- 数据:增删改查
-
- 程序:输入,计算,输出
-
- 函数:某一段功能代码
-
- 类:对现实事物的抽象
-
- 对象:类的实例
# 默认是今天
data = {
'time': '',
'thing': ''
}
def add_memo(item):
"""默认添加今天日期"""
now = datetime.now().strftime('%Y-%m-%d %H:%M')
print(now)
data['time'] = now
data['thing'] = item
return data
add_memo("饿了")
2019-02-13 00:26
{'time': '2019-02-13 00:26', 'thing': '饿了'}
指定日期
- 明天提醒我去趟公司
- 下个月6号去买2斤玉米
s = '明天提醒我去趟公司'
s.find('明天') # 日期的中文关键词
0
from dateutil.relativedelta import relativedelta
if s.find('明天') > -1:
# now = datetime.now()
# print(now)
# print(now + relativedelta(days=1)) # TODO
print((now + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M'))
2019-02-13 23:57
ss = '下个月5号去大栅栏买2斤花生米'
if ss.find('下个月') > -1:
# now = datetime.now()
# print(now)
# print(now + relativedelta(months=1, day=5)) # TODO
print((now + relativedelta(months=1, day=5)).strftime('%Y-%m-%d %H:%M'))
2019-03-05 23:57