python – 除周末外的两个日期之间的时间
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 除周末外的两个日期之间的时间,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3674字,纯文字阅读大概需要6分钟。
内容图文
![python – 除周末外的两个日期之间的时间](/upload/InfoBanner/zyjiaocheng/795/5272ba49c3f2405d9e1ec95e51dabdfb.jpg)
我需要一个函数来计算除周末日之外的两个日期之间的时间,以下是这样的:
# friday 9 PM
start_date = datetime.datetime(2015, 9, 18, 21, 0, 0)
# monday 3 AM
end_date = datetime.datetime(2015, 9, 21, 3, 0, 0)
# should return 6 hours
time = time_between_two_dates_except_weekends(start_date, end_date)
我实现了自己的功能,这是有效的,但它看起来不必要地庞大而复杂.我认为它可以更简单.
import datetime
from dateutil.relativedelta import relativedelta
from dateutil.rrule import DAILY, rrule
def time_between_two_dates_except_weekends(start_date, end_date):
WEEKEND_DAYS = [5, 6]
result = datetime.timedelta()
if all([start_date.year == end_date.year, start_date.month == end_date.month, start_date.day == end_date.day]):
result += datetime.timedelta(seconds = (end_date-start_date).seconds )
return result
day_after_start_date = start_date + relativedelta(days=1)
day_after_start_date = day_after_start_date.replace(hour=0, minute=0, second=0)
day_before_end_date = end_date - relativedelta(days=1)
if start_date.weekday() not in WEEKEND_DAYS:
result += datetime.timedelta(seconds = (day_after_start_date - start_date).total_seconds())
dates_range = rrule(
DAILY,
byhour=0,
byminute=0,
bysecond=0,
dtstart=day_after_start_date,
until=day_before_end_date
)
for date in dates_range:
if date.weekday() not in WEEKEND_DAYS:
result += datetime.timedelta(seconds=24 * 60 * 60)
if end_date.weekday() not in WEEKEND_DAYS:
end_date_beginning = end_date.replace(hour=0, minute=0, second=0)
result += datetime.timedelta(seconds = (end_date - end_date_beginning).total_seconds())
return result
有没有办法改善这个?
UPD.事实证明,不仅我的代码很复杂,而且在某些极端情况下返回不正确的结果(例如,当开始或结束日期的周末日期过去时).我建议只使用下面正确答案的代码
解决方法:
from datetime import timedelta
def diff(s, e):
_diff = (end_date - start_date)
while s < e:
if s.weekday() in {5, 6}:
_diff -= timedelta(days=1)
s += timedelta(days=1)
return timedelta(seconds=_diff.total_seconds())
如果您的日期可以在周末结束或开始,我们需要将它们移动到下一个星期一,我们可以使用帮助函数来执行:
from datetime import timedelta
def helper(d):
if d.weekday() == 5:
d += timedelta(days=1)
return d.replace(hour=0, minute=0, second=0, microsecond=0)
def diff(s, e):
if e.weekday() in {5, 6}:
e = helper(e)
if s.weekday() in {5, 6}:
s = helper(s)
_diff = (e - s)
while s < e:
if s.weekday() in {5, 6}:
_diff -= timedelta(days=1)
elif s.weekday() == 0:
s += timedelta(days=4)
s += timedelta(days=1)
return timedelta(seconds=_diff.total_seconds())
仍然跑得快一点:
In [57]: timeit time_between_two_dates_except_weekends(start_date,end_date)
10 loops, best of 3: 95.5 ms per loop
In [58]: timeit diff(start_date,end_date)
100 loops, best of 3: 12.4 ms per loop
In [59]: diff(start_date,end_date)
Out[59]: datetime.timedelta(7699, 9300)
In [60]: time_between_two_dates_except_weekends(start_date,end_date)
Out[60]: datetime.timedelta(7699, 9300)
只是做数学:
from datetime import timedelta, datetime
def helper(d):
if d.weekday() == 5:
d += timedelta(days=1)
return d.replace(hour=0, minute=0, second=0, microsecond=0)
def diff(s, e):
weekend = {5, 6}
both = e.weekday() in weekend and s.weekday() in weekend
is_weekend = e.weekday() in {5, 6} or s.weekday() in {5, 6}
if e.weekday() in weekend:
e = helper(e)
if s.weekday() in weekend:
s = helper(s)
_diff = (e - s)
wek = _diff.days / 7 * 2 + is_weekend - both
if s.weekday() > e.weekday() and not is_weekend:
wek += 2
return timedelta(seconds=_diff.total_seconds()) - timedelta(wek)
哪个运行得快得多:
In [2]: start_date = datetime(2016, 02, 29, 21, 25, 0)
In [3]: end_date = datetime(2045, 9, 02, 03, 56, 0)
In [4]: timeit diff(start_date,end_date)
100000 loops, best of 3: 6.8 μs per loop
In [5]: diff(start_date,end_date)
Out[5]: datetime.timedelta(7699, 9300)
内容总结
以上是互联网集市为您收集整理的python – 除周末外的两个日期之间的时间全部内容,希望文章能够帮你解决python – 除周末外的两个日期之间的时间所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。