python学习笔记02-时间


感觉datetime模块更好用些

1. time模块

时间元组: (年,月,日,时,分,秒,周几,年中第几天,是否夏令时),手工指定时,最后3项可以指定为0;
时间戳:指定时间距1970-01-01 00:00:00总秒数,float型数;

>>> import time  

1.1. 求当前时间戳

>>> time.time() # 1531722744.1899934,float型数  

1.2. 求给定时间的时间戳(输入时间元组)

>>> t = (2018,7,16,14,38,59,0,0,0) # 时间元组,最后3项可以指定为0  
>>> time.mktime(t) # 1531723139.0,给定时间的时间戳,注意参数只有一个而不是9个  

1.3. 按指定格式显示当前时间,返回字符串

>>> time.strftime('%Y-%m-%d %H:%M:%S') # '2018-07-16 14:54:26',返回str  

1.4. 指定时间字符串,按指定格式拆分为数组

>>> str = '2018-07-1615:20:00'  
>>> time.strptime(str, '%Y-%m-%d %H:%M:%S') # 返回time.struct_time  

返回time.struct_time(tm_year=2018, tm_mon=7, tm_mday=16, tm_hour=15, tm_min=20, tm_sec=0, tm_wday=0, tm_yday=197, tm_isdst=-1)
如果时间格式串与字符串不匹配会报告错误:time data xxx does not match format ‘%xxx’

1.5. 显示英文时间

>>> t = (2018,7,16,14,38,59,0,0,0)  
>>> time.asctime(t) # 'Mon Jul 16 14:38:59 2018',返回str  

1.6. 进程挂起1s, 0.1s时间

>>> time.sleep(1)
>>> time.sleep(0.1)

1.7. 格式化字符串

格式说明
%y两位数年份(00-99)
%Y四位数年份(0000-9999)
%m月份(01-12)
%d月内的一天(0-31)
%H24小时制小时数(0-23)
%I12小时制小时数(01-12)
%M分钟数(00=59)
%S秒(00-59)
%a本地简化星期名称
%A本地完整星期名称
%b本地简化的月份名称
%B本地完整的月份名称
%c本地相应的日期表示和时间表示
%j年内的一天(001-366)
%p本地A.M.或P.M.的等价符
%U一年中的星期数(00-53)星期天为星期的开始
%w星期(0-6),星期天为星期的开始
%W一年中的星期数(00-53)星期一为星期的开始
%x本地相应的日期表示
%X本地相应的时间表示
%Z当前时区的名称
%%%号本身

2. datetime模块

时间元组: (年,月,日,时,分,秒,微秒),注意这个时间元组有7个元素;
时间戳:给定的时间距离开始时间(1970-01-01 00:00:00)总秒数,float型数;

datetime模块中有一个datetime类,所有的信息都存储在这个类中

2.1. 初始化datatime类

>>> import datetime
>>> dt = datetime.datetime # 给datetime类一个别名
>>> type(dt)
# <class 'type'>

2.2. 得到一个指定具体时间的datetime类dt0

>>> dt0 = dt(2018,7,16,17,7,30,1)
>>> type(dt0)# 可以从dt0中取想要的数据
# <class 'datetime.datetime'>

2.3. 分别取年、月、日、时、分、秒、微秒

>>> dt0.year# 取年份, 返回值为int
2018
>>> dt0.month # 取月份, 返回值为int
7
>>> dt0.day# 取日期,返回值为int
16
>>> dt0.hour# 取时,返回值为int
14
>>> dt0.minute# 取分,返回值为int
29
>>> dt0.second# 取秒,返回值为int
20
>>> dt0.microsecond# 取微秒,返回值为int
253127

2.4. 取date和time

>>> dt0.date()# 取年月日, 返回datetime.date类
datetime.date(2018,7,16)
>>> dt0.time()# 取时间, 返回datetime.time类
datetime.time(17,7,30,1)

2.5. 取周几、日历

>>> # 取周几:
>>> dt0.weekday()#周一为0, 返回值为int
0
>>> dt0.isoweekday() #周一为1, 返回值为int
1
>>> dt0.isocalendar() # 取日历, 返回tuple,
(2018, 29,1)# 含义:(年,第几周,周几);

2.6. 公元天数换算

>>> dt0.toordinal() # 到公元元年的天数, 返回值为int
736891
>>> dt1 = dt0.fromordinal(54) # 指定到公元元年的天数,算datetime,返回datetime类
>>> dt1
datetime.datetime(1,2,23,0,0)

2.7. 取当前时间、零时区时间

>>> # 取当前时间:返回datetime类
>>> dt2 = dt.today()
>>> dt2
datetime.datetime(2018,7,17,10,31,53,757945)
>>> dt3 = dt.now()
>>> dt3
datetime.datetime(2018,7,17,10,31,53,758002)
>>>
>>> # 取零时区时间:返回datetime类
>>> dt4 = dt.utcnow()
>>> dt4 # 中国是东8区,所以零时区时间=中国时间-8 (东边日出早,小时数值大)
datetime.datetime(2018,7, 17, 2, 31, 53, 758017)

2.8. 取时间的标准str

>>> dt0.isoformat() # 得到时间的标准str,返回值为str
'2018-07-16T17:07:30.1'

2.9. 时间戳

>>> dt0.timestamp() # 从datetime取时间戳: 返回float,小数位表示毫秒数
1531732050.000001
>>> dt5 = dt0.fromtimestamp(1531732650.000001) # 从时间戳取datetime: 返回datetime类
>>> dt5
datetime.datetime(2018,7,16,17,17,30,1)

2.10. 自定义格式时间、英文格式时间

strptime与strftime作用是相反的.

>>> dt.strftime('%Y-%m-%d') # 按自定义格式返回时间str
'2018-07-16'
>>> dt.ctime() # 取英文格式的时间,返回str, 它可以通过strptime再转为datetime类.
'Mon Jul 16 17:07:30 2018'

2.11. 时间元组

>>> dt0.timetuple() # 得到9个元素的时间元组,
time.struct_time(tm_year=2018, tm_mon=7,tm_mday=16, tm_hour=17, tm_min=07, tm_sec=30,tm_wday=1, tm_yday=190,tm_isdst=-1)

2.12. 给定时间str,按时间格式拆开,返回datetime.datetime类

strptime与strftime作用是相反的.

>>> str='2049-12-31 23:59:59'
>>> dt6 = dt.strptime(str, '%Y-%m-%d %X')
>>> dt6
datetime.datetime(2049,12,31,23,59,59)
>>>
>>> # 有些EDA工具中的时间是如下内容: 'Mon Oct 28 16:10:24 2024', 把它转为datetime类.
>>> dt7 = dt.strptime('Mon Oct 28 16:10:24 2024', '%a %b %d %H:%M:%S %Y')
>>> dt7
datetime.datetimme(2024, 10, 28, 16, 10, 21)

2.13. datetime加减

datetime.datetime() - datetime.datetime() = datetime.timedelta()

>>> import datetime as dt
>>> 
>>> dt0 = dt.datetime(2025, 1, 10, 8, 0, 0, 0)
>>> dt1 = dt.datetime(2025, 2, 10, 9, 0, 0, 0)
>>> 
>>> #大-小
>>> td10 = dt1 - dt0
>>> type(td10) # <class 'module'>
>>> td10
datetime,tiledelta(31, 3600)
>>> 
>>> #只有.days和.seconds两个, 没有 .years, .months, .hours, .minutes, .microseconds等.
>>> td10.days    # 31  , 相差的天数, 可以是负数
>>> td10.seconds # 3600, 相差的秒数, 不会是负数, 是刨去整天数后剩下的秒数.
>>> 
>>> #秒数不会出现负数, 天数会出现负数
>>> #秒数如果不够减, 则要借一天的秒数(86400), 相应的天数要减1.
>>> dt.datetime(2025,1,10, 8,0,0, 0) - dt.datetime(2025,1,10, 8,0,10, 0)
datetime.timedelta(-1, 86390)
>>> # 24*60*60-10 = 86390
>>>

datetime.datetime() + datetime.timedelta() = datetime.datetime()

>>> now = datetime.datetime.now()
datetime.datetime(2017,8,23,14,21,33,796979)
>>>
>>> now + datetime.timedelta(hours=10)
datetime.datetime(2017,8,24,0,21,33,796979)
>>>
>>> now - datetime.timedelta(days=1)
datetime.datetime(2017,8,22,14,21,33,796979)
>>>
>>> now + datetime.timedelta(days=2, hours=12)
datetime.datetime(2017,8,26,2,21,33,796979)

#注意:
# timedelta参数有days, hours, minutes, seconds, microseconds, 但没有month, year.
>>> datetime.timedelta(days=1, hours=2, minutes=3, seconds=4, microseconds=5)

3. 把总秒数转为天/时/分/秒

假设一个总秒数268240,
转为时分秒为 : 74:30:40
转为天时分秒为: 2天02:30:40

>>> n = 268240    ; 总秒数
>>> 
>>> n%60          ; 刨去整分钟的秒数, 剩余的秒数
40                
>>> n//60         ; 整分钟数
4470              
>>> n//60%60      ; 刨去整小时的分钟数, 剩余的分钟数
30                
>>> n//60//60     ; 整小时数
74
>>> n//60//60%24  ; 刨去整天的小时数, 剩余的小时数
2
>>> n//60//60//24 ; 整天数
3
>>>

4 计算某年某月中包含多少天

# 方法1: 可以通过大小月与闰年来判断: 大月(一三五七八十腊), 小月(四六九冬), 闰月(需要根据年份定多少天)
#        但闰年的规则很多人并不完全清楚: 四年一闰, 百年不闰, 四百年再闰, ...
#
# 方法2: 通过计算本月与下个月的日期数目差来计算, 需要使用datetime类(或其它日期相关的类).

import datetime

def gen_current_month_days(i_year, i_month):
    n = 30 #默认30天

    if i_month==12:
        i_year_new  = i_year+1
        i_month_new = 1
    else:
        i_year_new  = i_year
        i_month_new = i_month+1

    o_dt_now  = datetime.datetime(i_year    , i_month    , 1, 0,0,0, 0)
    o_dt_next = datetime.datetime(i_year_new, i_month_new, 1, 0,0,0, 0)

    #本月一日到下月一日, 中间差的天数, 就是本月的天数
    n = (o_dt_next - o_dt_now).days

    return n

5 计算两个时间点相差的: 年月日时分秒

# 计算从o_dt_now 到 o_dt_target还有多少年, 多少月, 多少天, 多少小时, 多少分钟, 多少秒.
# 计算的重点在于"月日时分秒"不能出负数, 不够减时需要向高一级借.
# 如果使用大量if-else判断够不够减, 代码逻辑太复杂.
# 找到一个巧妙的办法: 先分别算出"年月日时分秒", 然后从秒向上依次判断是否为负, 如果为负则向上借1, 让当前层不为负.
# 这样不会有嵌套冗长的if-else.
def gen_dict_delta(o_dt_now, o_dt_target):
    _dict_delta = dict()

    _dict_delta['year'  ] = o_dt_target.year   - o_dt_now.year
    _dict_delta['month' ] = o_dt_target.month  - o_dt_now.month
    _dict_delta['day'   ] = o_dt_target.day    - o_dt_now.day
    _dict_delta['hour'  ] = o_dt_target.hour   - o_dt_now.hour
    _dict_delta['minute'] = o_dt_target.minute - o_dt_now.minute
    _dict_delta['second'] = o_dt_target.second - o_dt_now.second

    if _dict_delta['second'] < 0:
        #second为负, 借一分钟来用
        _dict_delta['second'] += 60
        _dict_delta['minute'] -=  1

    if _dict_delta['minute'] < 0:
        #minute为负, 借一小时来用
        _dict_delta['minute'] += 60
        _dict_delta['hour'  ] -=  1

    if _dict_delta['hour'] < 0:
        #hour为负, 借一天来用, 一天有24小时
        _dict_delta['hour'] += 24
        _dict_delta['day' ] -=  1

    if _dict_delta['day'] < 0:
        #day为负, 借一月来用, 一个月的天数需要计算(具体方法见上一节的程序)
        _dict_delta['day'  ] += gen_current_month_days(o_dt_now.year, o_dt_now.month)
        _dict_delta['month'] -=  1

    if _dict_delta['month'] < 0:
        #month为负, 借一年来用
        _dict_delta['month'] += 12
        _dict_delta['year' ] -=  1

    #if _dict_delta['year'] < 0:
    #    #year为负, 不用借了, 就这样吧

    return _dict_delta


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值