日期的转换及计算
对于日期,有时需执行不同时间单位的转换,或者接受字符串格式的日期,转换为 datetime 对象。有时需计算日期的范围,以及特定某个星期几的日期。这里更多用到的是 Python 提供的 datetime 模块。
datetime 模块
日期与时间的简单转换
datetime 模块中可以通过创建 timedelta 对象表示一个时间段。如下示例:
> from datetime import timedelta > a = timedelta(days=2, hours=6) > b = timedelta(hours=4.5) > c = a + b > c datetime.timedelta(2, 37800) > c.days 2 > c.seconds 37800 > c.seconds / 3600 10.5 > c.total_seconds() / 3600 58.5
如果想表示指定的日期和时间,需要先创建 datetime 对象然后使用标准数学运算执行操作。示例如下:
> from datetime import datetime > a = datetime(2020, 1, 15) > print(a + timedelta(days=10)) 2020-01-25 00:00:00 > b = datetime(2020, 2, 3) > d = b - a > d datetime.timedelta(19) > d.days 19 > now = datetime.today() > print(now) 2020-01-15 10:59:10.230995 > print(now + timedelta(minutes=10)) 2020-01-15 11:09:10.230995
datetime 对象能够自行处理闰年的问题,如下示例:
> a = datetime(2020, 3, 1) > b = datetime(2020, 2, 28) > a - b datetime.timedelta(2) > (a - b).days 2 > c = datetime(2019, 3, 1) > d = datetime(2019, 2, 28) > c - d datetime.timedelta(1) > (c - d).days 1
字符串与日期的转换
当编写的程序接受以字符串格式表达的日期输入时,需求为将此类字符串转换为 datetime 对象进行计算。
使用 datetime 对象中的 strptime() 方法实现,如下代码:
> from datetime import datetime > text = '2020-01-15' > y = datetime.strptime(text, '%Y-%m-%d') > y datetime.datetime(2020, 1, 15, 0, 0) > z = datetime.now() > z datetime.datetime(2020, 1, 15, 11, 10, 11, 71792) > diff = z-y > diff datetime.timedelta(0, 40211, 71792)
上述 %Y 的含义是以十进制表示的带世纪的年份,%m 为以补零后的十进制表示的月份,%d 为以补零后的十进制表示月份中的一天。
以下是几项格式代码。例如:
指令
含义
%a
当地工作日的缩写
% A
当地工作日的全名
% b
当地月份的缩写
% B
当地月份的全名
% H
补零后十进制表示的小时(24小时制)
% I
补零后十进制表示的小时(12小时制)
% M
补零后十进制表示的分钟
% S
补零后十进制表示的秒
将日期格式化为英文易读形式,如下:
> z datetime.datetime(2020, 1, 15, 11, 10, 11, 71792) > format_z = datetime.strftime(z, "%A %B %d, %Y") > format_z 'Wednesday January 15, 2020'
datetime.strftime() 函数返回一个由显示格式字符串所指定的代表日期的字符串。格式指令,如上述代码中的 "%A %B %d, %Y"。其中该函数的第一个参数为 datetime 对象。
这里需要注意的地方是,strptime 的性能比较差。若明确需求是解析大量并且已经知道格式的日期字符串,可以考虑自己实现一套解析方案。假设格式如 YYYY-MM-DD,可用如下代码实现解析函数:
from datetime import datetime def parse_ymd(s): year_s, mon_s, day_s = s.split('-') return datetime(int(year_s), int(mon_s), int(day_s))
两者实现的效果:
In [1]: from datetime import datetime ...: def parse_ymd(s): ...: year_s, mon_s, day_s = s.split('-') ...: return datetime(int(year_s), int(mon_s), int(day_s)) In [2]: text = "2020-01-15" In [3]: %timeit datetime.strptime(text, '%Y-%m-%d') 7.75 µs ± 31 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) In [4]: %timeit parse_ymd(text) 1.05 µs ± 3.07 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
可以看出,parse_ymd() 函数比 datetime.strptime() 快 7 倍多。若是进行大量处理的设计日期,且格式固定的情况下,可以考虑这个方案。
计算某个月份的日期范围
Python 提供的 calendar 模块提供了与日历相关的函数。可以考虑配合 datetime 模块实现需求:
#!/usr/bin/env python # -*- coding:utf-8 -*- ''' @File: datetime_calendar.py @Time: 2020/01/15 12:46:58 @Author: 大梦三千秋 @Contact: yiluolion@126.com ''' # put the import lib here from datetime import date, timedelta import calendar def get_month_range(start_date=None): '''获取月份的范围 Args: start_date: 开始的日期,默认为 None Returns: 返回包含月份开始日期和结束日期的元组 ''' if start_date is None: # 若 start_date 为空,赋值为当月的第一天 start_date = date.today().replace(day=1) # 获取月份的天数 _, days_in_month = calendar.monthrange(start_date.year, start_date.month) # 计算结束日期 end_date = start_date + timedelta(days=days_in_month) # 返回开始日期和结束日期的元组 return (start_date, end_date)
在交互式解释器中使用如下:
In [1]: from datetime import timedelta In [2]: from datetime_calendar import get_month_range In [3]: a_day = timedelta(days=1) In [4]: first_day, last_day = get_month_range() In [5]: while first_day < last_day: ...: print(first_day) ...: first_day += a_day ...: 2020-01-01 2020-01-02 2020-01-03 2020-01-04 2020-01-05 2020-01-06 2020-01-07 2020-01-08 ...
注意:若在交互解释器下无法导入自己写的模块中的方法,尝试直接在文件所在的路径下打开交互解释器。
上面的代码中,首先将 start_date 对应月份的第一天的日期计算出来。这里使用了 date 对象的 replace() 方法将 day 属性设置为 1,即表示第一天。
calendar.monthrange() 函数返回指定年份指定月份第一天是星期几,以及这个月的天数。
获得月份天数后,加上开始日期可得结束日期。这里需要注意的是,结束日期并不包含在这个日期范围。在遍历的时候,判断条件为 first_day < last_day,不输出 last_day 的值,以 timedelta 实例进行递增日期。
参考资料
来源
- David M. Beazley;Brian K. Jones.Python Cookbook, 3rd Edtioni.O'Reilly Media.2013.
- "8.1. datetime — Basic date and time types".docs.python.org.Retrieved 11 January 2020
- "8.2. calendar — General calendar-related functions".docs.python.org.Retrieved 13 January 2020
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 明达年度发烧碟MasterSuperiorAudiophile2021[DSF]
- 英文DJ 《致命的温柔》24K德国HD金碟DTS 2CD[WAV+分轨][1.7G]
- 张学友1997《不老的传说》宝丽金首版 [WAV+CUE][971M]
- 张韶涵2024 《不负韶华》开盘母带[低速原抓WAV+CUE][1.1G]
- lol全球总决赛lcs三号种子是谁 S14全球总决赛lcs三号种子队伍介绍
- lol全球总决赛lck三号种子是谁 S14全球总决赛lck三号种子队伍
- 群星.2005-三里屯音乐之男孩女孩的情人节【太合麦田】【WAV+CUE】
- 崔健.2005-给你一点颜色【东西音乐】【WAV+CUE】
- 南台湾小姑娘.1998-心爱,等一下【大旗】【WAV+CUE】
- 【新世纪】群星-美丽人生(CestLaVie)(6CD)[WAV+CUE]
- ProteanQuartet-Tempusomniavincit(2024)[24-WAV]
- SirEdwardElgarconductsElgar[FLAC+CUE]
- 田震《20世纪中华歌坛名人百集珍藏版》[WAV+CUE][1G]
- BEYOND《大地》24K金蝶限量编号[低速原抓WAV+CUE][986M]
- 陈奕迅《准备中 SACD》[日本限量版] [WAV+CUE][1.2G]