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_timeyear=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
posted @ 2019-02-24 23:13  lataku~~  阅读(131)  评论(0编辑  收藏  举报