日期时间范围上的Python过滤器?

日期时间范围上的Python过滤器?,python,datetime,Python,Datetime,我有一些以日期时间格式显示开始和结束时间的数据,我想根据更严格的日期范围计算以小时为单位的持续时间。但到目前为止,我还没有成功。仍然是python的业余爱好者 例子:约翰·多伊从1990-01-01T00:00:00.0到2016-12-31T23:59:59.0住在主街123号,但我想知道2015年10月到12月他在那里住了多少小时 下面的代码将成功计算小时数,但我无法成功筛选日期时间,因此我只能得到2015年10月1日和2015年12月31日之间的小时数 from datetime impo

我有一些以日期时间格式显示开始和结束时间的数据,我想根据更严格的日期范围计算以小时为单位的持续时间。但到目前为止,我还没有成功。仍然是python的业余爱好者

例子:约翰·多伊从1990-01-01T00:00:00.0到2016-12-31T23:59:59.0住在主街123号,但我想知道2015年10月到12月他在那里住了多少小时

下面的代码将成功计算小时数,但我无法成功筛选日期时间,因此我只能得到2015年10月1日和2015年12月31日之间的小时数

from datetime import datetime

# The getValue function retrieves the datetime values from the table
time1str = getValue("START_DT_TM")
time2str = getValue("STOP_DT_TM")

# Intended date range
# periodstart = datetime.strptime("2015-10-01T00:00:00.0", '%Y-%m-%dT%H:%M:%S.%f')
# periodend = datetime.strptime("2015-12-31T23:59:59.0", '%Y-%m-%dT%H:%M:%S.%f')

time1 = datetime.strptime(time1str, '%Y-%m-%dT%H:%M:%S.%f')
time2 = datetime.strptime(time2str, '%Y-%m-%dT%H:%M:%S.%f')
timen = datetime.strptime(nowstr, '%Y-%m-%d %H:%M:%S.%f')
timef = (time2-timen).days*24

if timef > 0:
    delta = timen - time1
    seconds = delta.seconds/1440
    days = delta.days*24
    return str(days+seconds)
else:
    delta = time2 - time1
    seconds = delta.seconds/1440
    days = delta.days*24
    return str(days+seconds)

我用这个方法计算一段时间内从周一到周五的工作日

from datetime import date, timedelta

def working_days(fromdate, todate):
    daygenerator = (fromdate + timedelta(x + 1) for x in xrange((todate - fromdate).days))
    return sum(1 for day in daygenerator if day.weekday() < 5)

print working_days(date(2018,01,10), date(2018,11,09))

我还是个初学者,所以可能有人会以更好的方式帮助你。

你需要做两件事:

确定你的射程是否需要调整;如果有人在10月1日之后才搬到这个地方,那么你需要选择他们实际开始住在房子的晚些日期。这同样适用于结束日期

然后计算根据需要调整的开始日期和结束日期之间的小时数。考虑到这可能是0

我在这里省略了将值转换为datetime对象;你已经记对了。因此,假设time1和time2是一个人居住在某个地址的开始和结束时间,periodstart和periodend是您想要知道小时数的边界:

# Adjust the start, pick the later value
periodstart = max(periodstart, time1)
# Adjust the end, pick the earlier value
periodend = min(periodend, time2)

duration = periodend - periodstart
hours = duration.total_seconds() // 3600
我在这里使用了.days属性,而不是.days属性,以确保在小时计数中包含一天的持续时间分数

演示:

当时间1或时间2在以下时间段内时,这仍然适用:

>>> from datetime import timedelta
>>> time1 = periodstart + timedelta(days=25) # moved in after the periodstart date
>>> periodstart = max(periodstart, time1)
>>> periodend = min(periodend, time2)
>>> duration = periodend - periodstart
>>> duration.total_seconds() // 3600
1607.0
>>> time1, time2 = datetime(1990, 1, 1, 0, 0), datetime(2016, 12, 31, 23, 59, 59)
>>> periodstart, periodend = datetime(2015, 10, 1, 0, 0), datetime(2015, 12, 31, 23, 59, 59)
>>> time2 = periodend - timedelta(days=42)   # moved out before periodend
>>> periodstart = max(periodstart, time1)
>>> periodend = min(periodend, time2)
>>> duration = periodend - periodstart
>>> duration.total_seconds() // 3600
1199.0

为什么不计算2015年10月1日至2015年12月31日之间的小时数?对于任何范围,你只需要通过简单的比较来确定上限和下限,然后找到该范围内的小时数,就像你刚才说的那样,我应该更清楚。问题是,在我处理的数据中,有多个持续时间重叠在10月1日至12月31日的范围内。因此,使用同一个例子,考虑四种不同的情况:亚当在该时期之前生活在那里,但在此期间移出;鲍勃在月经开始后就开始住在那里,但在月经结束前就离开了;克里斯在月经开始后开始住在那里,但在月经结束后离开;戴夫在期末前后都住在那里。我需要能够计算出每个人在某个范围内的停留时间。我不确定确切的原因,但这返回了错误的结果。它给了我X在Y地方住了多久的完整时间,而不仅仅是他在10月1日到12月31日期间在那里住了多久。所以,我应该得到一个大约在0到92天之间或相当于小时的结果,但它给了我例如3000天,因为他在那里住了几年。@BrianDonohue:除了在减法中交换periodend和periodstart之外,对于您给定的输入,我得到了正确的答案2207小时。
>>> from datetime import datetime, timedelta
>>> time1, time2 = datetime(1990, 1, 1, 0, 0), datetime(2016, 12, 31, 23, 59, 59)
>>> periodstart, periodend = datetime(2015, 10, 1, 0, 0), datetime(2015, 12, 31, 23, 59, 59)    
>>> periodstart = max(periodstart, time1)
>>> periodend = min(periodend, time2)
>>> duration = periodend - periodstart
>>> duration
datetime.timedelta(91, 86399)
>>> duration.total_seconds() // 3600
2207.0
>>> from datetime import timedelta
>>> time1 = periodstart + timedelta(days=25) # moved in after the periodstart date
>>> periodstart = max(periodstart, time1)
>>> periodend = min(periodend, time2)
>>> duration = periodend - periodstart
>>> duration.total_seconds() // 3600
1607.0
>>> time1, time2 = datetime(1990, 1, 1, 0, 0), datetime(2016, 12, 31, 23, 59, 59)
>>> periodstart, periodend = datetime(2015, 10, 1, 0, 0), datetime(2015, 12, 31, 23, 59, 59)
>>> time2 = periodend - timedelta(days=42)   # moved out before periodend
>>> periodstart = max(periodstart, time1)
>>> periodend = min(periodend, time2)
>>> duration = periodend - periodstart
>>> duration.total_seconds() // 3600
1199.0