我想解决一个相当独特的问题:
根据此样本数据(实际数据是非常多的记录,每张卡每天至少4张):
serial, card, rec_date, rec_time, retrieved_on
2976 00040 2010-07-29 18:57 2010-07-31 13:37:31
2977 00040 2010-07-30 09:58 2010-07-31 13:37:31
2978 00040 2010-07-30 15:33 2010-07-31 13:37:31
2979 00040 2010-07-30 16:13 2010-07-31 13:37:31
2980 00040 2010-07-30 19:41 2010-07-31 13:37:31
记录来自时钟系统。
我想要做的是选择一组条目,按card
和rec_date
过滤,然后确定此人在白天工作的时间和每个工作时间的长度,如何他/她已经休息了许多休息时间,并在本周末获得了总工作时数。
从上面的列表中,2977
是签入,然后2978
是签出,依此类推。
我迷失了如何做到这一点,所以我认为这里有人会有一个想法。
我从其他地方导入其他数据后使用一个简单的类来存储这些数据:
class TimeClock(models.Model):
serial = models.CharField(max_length = 16)
card_no = models.CharField(max_length = 10)
rec_date = models.DateField()
rec_time = models.TimeField()
oper_date = models.DateTimeField(default=datetime.today)
答案 0 :(得分:2)
显然,TimeClock类本身就不适合你正在做的事情。
您需要总结TimeClock以创建可以使用的WorkIntervals。这些是显示工作范围(理论)开始和结束的TimeClock行对。
如果有人未能入时,你完全无法推断出正在发生的事情。 这不是“难”,这是不可能的。
此外,如果有人在午夜过夜,你无法推断出发生的事情。 这不是“难”,这是不可能的。
但是,我们会假装没有人在午夜过夜,也没有人无法进出(hahaha)
def make_pairs( tc_query_set ):
start = None
for row in tc_query_set:
if start is None:
start= row
continue
elif start.card == row.card and start.rec_date == row.rec_date:
yield start, row
start= None
else:
# May as well raise an exception -- the data cannot the processed
yield start, None
start= row
您可以按如下方式使用。
data = TimeClock.objects.order_by('card','rec_date','rec_time').all()
for start, end in make_pairs( data ):
WorkIntervals.objects.create( start.card, start.rec_date, start.rec_time, end.rec_time, ... )
现在您可以使用间隔。如果可以创建它们。
答案 1 :(得分:1)
嗯,这里有一堆独立的问题。我假设您已经获得了过滤数据,因此您的日志看起来像特定日期的唯一卡的所有事件。假设此数据存储为log
中的字符串列表。然后:
import datetime
def dates( log ):
''' Yields consecutive datetimes in the log. '''
for event in log:
yield datetime.datetime.strptime( event[ 12 : 28 ], "%Y-%m-%d %H:%M" )
def time_clocked_in( log ):
assert not len( log ) % 2
total_time = datetime.timedelta( 0 )
event_dates = dates( log )
try:
while 1:
total_time -= next( event_dates ) - next( event_dates )
except StopIteration:
pass
return total_time
log = [
"2977 00040 2010-07-30 09:58 2010-07-31 13:37:31",
"2978 00040 2010-07-30 15:33 2010-07-31 13:37:31",
"2979 00040 2010-07-30 16:13 2010-07-31 13:37:31",
"2980 00040 2010-07-30 19:41 2010-07-31 13:37:31"
]
print( time_clocked_in( log ) )
>>> 9:03:00